# Practo Scraper — India Doctor List, Fees & Clinics (`s-r/practo-scraper`) Actor

Build a doctor list from Practo by city and specialty: names, experience, qualifications, clinic, locality, consultation fee and patient recommendations, with optional profile details. For healthcare lead generation and market research.

- **URL**: https://apify.com/s-r/practo-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (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 $5.00 / 1,000 doctor records

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Practo Scraper — India Doctor List with Fees and Clinics

Practo scraper for building a doctor list from Practo by city and specialty: names, specialties, years of experience, qualifications, clinic, locality, consultation fee and patient recommendations. Use it for healthcare lead generation, provider market research and fee comparisons, and add public profile details for medical registrations, languages, awards and practice relationships.

### What the Practo scraper collects

Use these records to compare the providers listed in a city, study consultation prices, organise a doctors directory or prepare a list of practices for further research. Each result represents a doctor at one particular practice. A doctor who appears at two clinics can therefore produce two rows. The `doctor_id` links those rows to the same practitioner, while `place_id` identifies the doctor and practice relationship.

India is the active market. Public pages for Singapore, the Philippines and Indonesia may still contain archived records after Practo closed those markets. These rows have `market_status: "archived"` and a warning in the run output. Treat them as historical directory information: the doctor may have moved, the fee may have changed and appointments may no longer be available. Availability of archived records can change without notice.

This version collects doctors. Clinic names, addresses and practice information are included on those doctor rows. Separate clinic directory records are outside this version's coverage.

### How to use the Practo scraper

1. Enter a city and a specialty as they appear in Practo's web addresses, for example `bangalore` and `dermatologist`, or paste a doctor search URL copied from Practo.
2. Set `maxItems` to the number of doctor rows you need.
3. Turn on `details` only when you need registrations, languages, awards or the full list of practices.
4. Start the run and download the dataset as JSON, CSV, Excel or HTML, or read it through the Apify API.

### Input

Provide `city` and `specialty`, using Practo's URL slugs, or supply one or more public doctor listing URLs in `searchUrls`. An optional `locality` narrows a city search to a neighbourhood. Listing URLs retain their query filters, so you can copy a filtered doctor search from Practo. Search URLs take precedence over city, specialty and locality.

This search was verified against public Practo records:

```json
{"city":"bangalore","specialty":"dermatologist","maxItems":10,"details":false}
```

Set `maxItems` from 1 to 1000; it defaults to 50 and applies to the combined unique results across all supplied searches. Set `details: true` to request a matching public profile for each delivered doctor row. Without that option, the listing already supplies the doctor name, specialty, qualifications, experience, clinic, location, consultation fee and recommendation information.

Compatibility input names include `speciality`, `startUrl`, `startUrls`, `enrichDetails` and `scrapeDetails`. Use the canonical names for new integrations. When both names are supplied, the canonical value takes precedence. Unknown city or specialty slugs are reported as searches with no results; the actor does not guess a replacement city or correct spelling. A search in a country that Practo has discontinued without keeping its pages, such as Malaysia, ends with a not-found error straight away and is not charged.

### Output

The default dataset holds one row per unique doctor and practice relationship. Core fields are `name`, `place_id`, `url`, `fetched_at`, `category`, `categories`, `address`, `street`, `city`, `postal_code`, `country_code`, `lat`, `lng` and `reviews_count`. The `source` is `practo-scraper` and the `platform` is `practo`.

Additional listing fields include `doctor_id`, `practice_id`, `experience_years`, `qualifications`, `clinic_name`, `practice_type`, `locality`, `consultation_fee`, `currency`, `recommendation_percent`, `patients_count`, `services`, `timings`, `next_available_at` and `market_status`. Monetary amounts are numeric and keep their source currency. A source fee of zero becomes `null`, because the page does not establish that consultation is free.

Practo's recommendation percentage uses a 0–100 scale. It is delivered as `recommendation_percent`; it is not converted to a doctor star rating. Aggregate search ratings and ratings for practices inside optional profile details have their own fields. Missing source values remain `null` where supported.

With details enabled, successfully read profiles add `registrations`, `registration_verified`, `languages`, `memberships`, `awards`, `experiences`, `procedures`, `specialist_years_of_experience`, `practices` and recommendation counters. `details_fetched` tells you whether the matching profile was parsed. If a profile fails, its listing row remains in the dataset, the detail charge is omitted and the run records a warning. Masked phone numbers and email addresses are excluded.

#### Practo doctor data example

This is the first row of a real run for dermatologists in Bangalore, collected on 5 October 2026. It is shortened for reading: the `services` list held 98 entries and two of the three qualifications are left out. The values are what the source showed on that date, not a promise about a future run.

```json
{
  "source": "practo-scraper",
  "platform": "practo",
  "fetched_at": "2026-10-05T09:02:00.238Z",
  "name": "Dr. Parthasarathi Dutta Roy",
  "place_id": "243591",
  "doctor_id": 311620,
  "practice_id": 729170,
  "url": "https://www.practo.com/bangalore/doctor/dr-partha-sarathi-dutta-roy-dermatologist-cosmetologist-dermatologist?practice_id=729170&specialization=Dermatologist",
  "address": "Number G-2, Ground Floor, Sadath Court, Ashok Nagar, Magrath Road, Bangalore, 560025",
  "city": "Bangalore",
  "postal_code": "560025",
  "country_code": "IN",
  "lat": 12.970388898279,
  "lng": 77.610510732047,
  "category": "Dermatologist",
  "reviews_count": 5091,
  "experience_years": 23,
  "qualifications": [
    {"qualification": "MBBS", "college": "Sri Siddhartha Medical College & Research", "completion_year": 2003}
  ],
  "clinic_name": "Dr. Partha Sarathi's Asian Hair And Skin Hospitals",
  "practice_type": "Hospital",
  "locality": "Magrath Road",
  "consultation_fee": 900,
  "currency": "INR",
  "recommendation_percent": 88,
  "patients_count": 5091,
  "wait_time_minutes": 15,
  "services": ["Medical Vitiligo Treatment", "Electrocaurtry", "Laser Hair Removal - Face"],
  "services_count": 98,
  "timings": [
    {"begin_time": "10:30", "end_time": "20:30", "available_days": ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"]}
  ],
  "market_status": "active",
  "search_url": "https://www.practo.com/bangalore/dermatologist",
  "rank": 1
}
```

### Use cases for a Practo doctor list

- **Healthcare lead generation.** Build a list of clinics and hospitals per city and specialty for medical equipment, pharma, software or insurance sales, with clinic name, address and coordinates on every row.
- **Market research.** Count providers per specialty and locality, compare experience levels and see where a specialty is thin or crowded.
- **Consultation fee benchmarks.** Compare fees across neighbourhoods, practice types and experience bands in one city or across cities.
- **Doctors database for India.** Keep a dated directory of public profiles, and run the same searches again later to see who joined, moved or changed fees.
- **Reputation tracking.** Follow the recommendation percentage and patient story counts of a set of practices over time.

### Practo scraper compared with other options

Several Practo actors already exist. Compared with them, this one makes these choices:

- **No start fee and free empty runs.** You pay for delivered doctor rows, and for profile details only when a profile was actually read. A search with no results costs nothing in data events.
- **One row per doctor and practice.** Doctors who work at several clinics are not merged into one address; `doctor_id` links their rows, and repeated rows are removed.
- **Honest values.** A missing fee stays empty instead of zero, and the recommendation percentage is not relabelled as a star rating.
- **Archived markets are labelled.** Singapore, Philippines and Indonesia rows are flagged as archived instead of being mixed with active Indian listings.

Copying data by hand from the website takes minutes per doctor and leaves you without the IDs needed to join later runs; a one-off custom script needs maintenance whenever the site changes.

### Pricing

Billing uses two delivery events: `doctor` counts each delivered doctor/practice row, and `doctor_details` counts each delivered row with a successfully parsed matching profile. Details are optional. There is no start event, and searches that return no rows incur no data event charge. The current event rates are shown in the actor's Pricing tab; those rates govern your run.

Non-paying accounts can receive up to ten rows per run. The same limit covers profile delivery, so turning on details cannot charge more than ten successful detail events on a free run. The total number of rows can be lower when Practo has fewer matching results or a public page becomes unavailable.

### Pagination and data quality

The actor follows continuation pages automatically and removes repeated `place_id` values. Practo can reorder results between requests, so its displayed total may exceed the unique rows collected. `maxItems` is a ceiling, not a guarantee. Keep the warnings and search summaries when comparing coverage across dates.

API responses include a `next_cursor` when further work remains. Direct API clients send it back as `cursor` with the same search and details options. The Apify actor handles that continuation for you. A `partial` result and its warnings explain interrupted work or unavailable details. Archived market warnings describe source status and do not imply that the records are active.

### FAQ

#### Can I get doctor phone numbers or email addresses?

No. The doctor pages expose masked contact values rather than complete contact details. Those values are excluded from the dataset. Use the public profile URL to inspect the provider's current listing.

#### Does this collect every clinic separately?

This version returns doctor listings, including the clinic where each doctor practises. It does not create separate clinic directory rows. Optional profile practices give additional public practice relationships for the doctor.

#### Why is the recommendation percentage different from a rating?

The percentage measures patient recommendations on Practo and ranges from zero to one hundred. A star rating has another scale and meaning. Keeping these values separate preserves the information the source actually provides.

#### Why did I receive fewer results than requested?

The search may have fewer providers than your limit, public records can disappear and results can move between pages. The actor deduplicates doctor/practice IDs and reports source or profile failures in its warnings.

#### Are Singapore, Philippines and Indonesia listings current?

Those records are archived where Practo marks the market as closed. Their fees, practice details and availability may be outdated. Filter `market_status` to distinguish them from active Indian listings.

#### Which countries does the Practo scraper cover?

India is the active market. Singapore, the Philippines and Indonesia return archived records where Practo still serves them. Practo sends searches for countries it has dropped entirely, such as Malaysia, back to its homepage; the actor reports those as not found without retrying, and they cost nothing.

#### Can I export the doctor list to Excel or CSV?

Yes. Every run stores its rows in an Apify dataset that you can download as CSV, Excel, JSON or HTML, or read through the API from your own tools.

#### Is it legal to scrape Practo?

The actor reads publicly visible listing and profile pages and leaves out masked contact values. Personal data rules such as India's data protection law can still apply to how you store and use the results; check them for your use case.

# Actor input Schema

## `city` (type: `string`):

City slug, for example bangalore. Required with specialty unless searchUrls is supplied.

## `specialty` (type: `string`):

Doctor specialty slug, for example dermatologist or dentist.

## `locality` (type: `string`):

Optional locality slug, for example jp-nagar.

## `searchUrls` (type: `array`):

Public Practo doctor listing URLs. Overrides city, specialty and locality.

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

Maximum unique doctor/practice rows across the search and its cursors.

## `details` (type: `boolean`):

Fetch public doctor profiles for registrations, languages, awards and practices.

## `cursor` (type: `string`):

Opaque next_cursor from a previous response. Keep the same search and details settings.

## `speciality` (type: `string`):

Compatibility alias for specialty; canonical field takes precedence.

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

Compatibility alias for searchUrls; canonical field takes precedence.

## `enrichDetails` (type: `boolean`):

Compatibility alias for details; canonical field takes precedence.

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

Compatibility alias for details; canonical field takes precedence.

## `startUrl` (type: `string`):

Compatibility alias for a single searchUrls entry.

## Actor input object example

```json
{
  "city": "bangalore",
  "specialty": "dermatologist",
  "maxItems": 50
}
```

# Actor output Schema

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

Unique doctor/practice listings.

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

Delivery counts and warnings.

# 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 = {
    "city": "bangalore",
    "specialty": "dermatologist",
    "maxItems": 50,
    "details": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/practo-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 = {
    "city": "bangalore",
    "specialty": "dermatologist",
    "maxItems": 50,
    "details": False,
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/practo-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 '{
  "city": "bangalore",
  "specialty": "dermatologist",
  "maxItems": 50,
  "details": false
}' |
apify call s-r/practo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/practo-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/vYbwCwD3DgDRio9P8/builds/TEZge8cTBiuppYjU7/openapi.json
