RateMDs Scraper [From $1.5💰] | Profiles | Reviews | Leads avatar

RateMDs Scraper [From $1.5💰] | Profiles | Reviews | Leads

Pricing

from $1.40 / 1,000 doctors

Go to Apify Store
RateMDs Scraper [From $1.5💰] | Profiles | Reviews | Leads

RateMDs Scraper [From $1.5💰] | Profiles | Reviews | Leads

Extract doctor profiles and patient reviews from RateMDs for reputation monitoring, healthcare lead generation and patient sentiment analysis. US & Canada data, structured JSON on Apify.

Pricing

from $1.40 / 1,000 doctors

Rating

0.0

(0)

Developer

Ahmed Jasarevic

Ahmed Jasarevic

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

RateMDs Scraper

A RateMDs scraper that extracts doctor profiles and patient reviews from RateMDs.com across the United States and Canada: 33 profile fields land in the default dataset and 15 review fields in a separate reviews dataset — built for reputation monitoring for doctors and healthcare review monitoring when no official RateMDs API exists.

Main use cases

  • Doctor reputation monitoring / online reputation management for doctors — track the five rating dimensions plus fresh patient reviews for a physician watchlist on a schedule.
  • Healthcare review monitoring — pull RateMDs reviews alongside the other physician rating websites (Healthgrades, Vitals, Zocdoc, WebMD) in a multi-site pipeline.
  • Patient sentiment analysis — analyze review text, star ratings and per-dimension sub-ratings to see how patients talk about a practice.
  • Healthcare lead generation — build doctor leads with ratings and reviews: profile rows carry phone, address, specialty, review count and average score.
  • Physician market research — scrape doctor reviews for a research dataset, or compare reviews across cities and specialties.
  • Find the best rated doctors in any US or Canadian city — search by state/city and specialty to surface top-rated physicians.

How it works

The actor runs a CheerioCrawler (no browser automation) with Apify residential proxies. In search mode it walks paginated listing pages (/best-doctors/{state}/{city}/[{specialty}]/?page={N}); in profile mode it fetches specific /doctor-ratings/{slug}/ profile URLs directly. It solves the site's HTTP 202 JavaScript proof-of-work challenge inside the request session, then reads structured data from server-rendered window.DATA JSON blobs, JSON-LD (Physician / MedicalWebPage / BreadcrumbList) and DOM fallbacks. Profiles land in the default dataset; reviews go to their own reviews dataset, fetched page by page from the server-rendered organic and partner review pages inside the profile's sticky-IP session.

Does RateMDs Have An API? (And How To Get Its Reviews)

RateMDs publishes no public API — there is no developer portal or documented endpoint for doctor or review data. That gap is why this actor exists: a RateMDs Reviews API substitute that returns the same data as structured JSON.

  • No official API: RateMDs exposes no documented REST endpoint, so programmatic access requires a scraper.
  • Programmatic reviews: start a run, then read the reviews dataset (15 fields per review) with GET /v2/datasets/<reviewsDatasetId>/items, or read both dataset URLs from GET /v2/actor-runs/:runId in output.profiles / output.reviews.
  • API-friendly output: an actor output schema (actorOutputSchemaVersion 1) publishes both dataset URLs, so downstream code fetches profiles and reviews without guessing storage IDs.

Scrape RateMDs Doctor Profiles And Patient Reviews

  • Two modes: search crawls listing pages by location and specialty; profile scrapes specific doctor profile URLs directly.
  • Dual-dataset writes: 33 profile fields (name, specialty, practice, address, phone, education, languages, geo-coordinates, five rating dimensions) to the default dataset; 15 review fields (text, date, stars, sub-ratings, author, appointment type, source) to the separate reviews dataset — each with its own schema and Output-tab view.
  • Parallel by default: maxConcurrency (default 10, max 20) fills every slot immediately; those slots share up to 3 sticky residential sessions, so the proof-of-work challenge is solved once per session, not once per request.
  • Review pagination handled: both organic (?page=N) and partner (?third_party_page=N) lists are walked — up to 10 pages per list per doctor, and pages after page 1 are prefetched in small parallel batches so doctors with hundreds of reviews no longer cost one round-trip per page.

Monitor Physician Reviews Across RateMDs, Healthgrades, Vitals And Zocdoc

Reputation-monitoring platforms list RateMDs as a monitored source alongside Healthgrades, Vitals, WebMD, Yelp and Zocdoc, so healthcare review monitoring needs the RateMDs slice too:

  • Run daily or weekly per doctor or per city/specialty to catch new reviews.
  • Every review row carries runId, date and source (organic / partner), so you can diff runs over time.
  • Profile rows carry reviewCount, averageScore and the five sub-ratings — a rating trend line per physician.
  • Reviews are stored page by page as they arrive, so a stopped run keeps every page it already fetched.

Build A Doctor Lead List With Ratings And Reviews

The profile dataset doubles as a doctor lead list for healthcare lead generation and provider data enrichment: contact and geo fields (phone, streetAddress, city, state, zipCode, country, latitude, longitude), credential context (name, specialty, practiceName, school, graduationYear, languages, openingHours, clinics), the ratings that qualify a lead (reviewCount, averageScore, overallRating, staffRating, punctualityRating, helpfulnessRating, knowledgeRating) and enrichment links (profileUrl, photoUrl). With search mode filtering by state/city and specialty, you can build geographically targeted physician lists for the US and Canada.

Patient Sentiment Analysis From Real Doctor Reviews

The dedicated reviews dataset is built for patient sentiment analysis and physician ratings data work:

  • Text: text holds the full review text (description plus title when present).
  • Ratings: rating (1-5 overall) plus staffRating, punctualityRating, helpfulnessRating, knowledgeRating sub-ratings per review.
  • Context: date, author, appointmentType (e.g. "Office visit") and source (organic = on RateMDs, partner = collected by a partner).
  • Joins: doctorName, doctorProfileUrl and runId link every review back to its profile row and run.

Because reviews live in their own dataset rather than embedded in profile items, you can aggregate thousands of reviews without re-parsing profile JSON.

Provider Data Enrichment For US And Canadian Doctors

Coverage is US + Canada only, enforced by the country enum (us / ca / both, default both). The 33 profile fields cover identity (name, gender, profileUrl), credentials (specialty, school, graduationYear), location, contact and practice, reputation (reviewCount, averageScore, overallRating, staffRating, punctualityRating, helpfulnessRating, knowledgeRating) and media/meta (photoUrl, breadcrumbTrail, scrapedAt).

location accepts state/city paths (tx/houston, on/toronto), country prefixes (us/, ca/) or full RateMDs URLs — cleaned up automatically.

Find The Best Rated Doctors In Any US Or Canadian City

RateMDs' own city ranking pages (e.g. "Best Doctors in Toronto, ON") prove the best-rated-doctors-in-city query pattern across US and Canadian cities. This actor answers it with search mode:

  • location takes a state or state/city slug (tx, tx/houston, on, on/toronto); specialty narrows to a slug (dentist, family-gp, dermatologist, cardiologist).
  • maxPages caps listing pages per location/specialty combination (0 = unlimited, default 10), following <link rel="next">; maxItems caps total profiles (0 = unlimited, default 100).

Input Parameters

All 11 input fields from input_schema.json. Only mode is required.

FieldTypeRequiredDefaultNotes
modesearch | profileYessearchsearch crawls listing pages by location/specialty; profile scrapes specific doctor profile URLs.
locationstringNo (search mode)""State/city path from the RateMDs URL, e.g. tx/houston, on/toronto. Country prefixes (us/, ca/) and full RateMDs URLs accepted. Missing value in search mode fails fast.
specialtystringNo""Specialty slug from the RateMDs URL path, e.g. dentist, family-gp, dermatologist. Used in search mode.
countryus | ca | bothNobothCountry to search: us, ca or both.
profileUrlsstring[]No (profile mode)[]Doctor profile URLs or slugs to scrape directly.
maxItemsintegerNo100Max doctor profiles. 0 = unlimited (capped by Apify limits).
maxPagesintegerNo10Max listing pages per location/specialty. 0 = unlimited.
includeReviewsbooleanNotrueScrape patient reviews into the separate reviews dataset. Increases scraping time significantly.
maxReviewsPerDoctorintegerNo5Max reviews per doctor. 0 = all; organic + partner lists, up to 10 pages per list per doctor.
maxConcurrencyintegerNo10Parallel requests, range 1-20. Up to 3 sticky residential sessions are shared by those requests, so PoW is solved once per session. 10+ slots need 1024 MB+ memory.
proxyobjectYes*residential prefillResidential proxies REQUIRED — datacenter IPs get HTTP 406. Prefill: {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}.
* Apify Proxy with the RESIDENTIAL group is mandatory; the actor fails with an explicit message if RateMDs returns 406.

Output Fields

The run's Output tab shows both outputs side by side — Doctor profiles and Patient reviews — each linking to its own dataset. GET /v2/actor-runs/:runId returns the same links in output.profiles / output.reviews.

Doctor profiles — default dataset, schema profiles_dataset_schema.json (33 fields)

One item per doctor; reviews are not embedded — they live in their own dataset. The default dataset declares its schema in .actor/actor.json (storages.datasets.default), so the Output tab renders a Doctors table and the field list is published to MCP/AI agents.

  • Identity: name, profileUrl, gender, specialty, photoUrl, breadcrumbTrail
  • Credentials: school, graduationYear
  • Address: streetAddress, city, state, stateSlug, country, zipCode, latitude, longitude
  • Contact and practice: phone, practiceName, clinics, openingHours, languages
  • Ratings: reviewCount (headline = organic + partner), averageScore, overallRating, staffRating, punctualityRating, helpfulnessRating, knowledgeRating
  • Meta: scrapedAt
  • Fallback-only (only when a review falls back into the default dataset): type (always "review"; profiles carry no type), runId, doctorName, doctorProfileUrl

Patient reviews — separate reviews dataset, schema reviews_dataset_schema.json (15 fields)

When includeReviews is true, every scraped review is written to its own dataset, declared under storages.datasets.reviews. The two storages are completely separate: the default dataset holds one item per doctor (Output-tab view Doctors), the reviews dataset one item per review (view Reviews).

  • Core: id (RateMDs rating id, de-duplicates reviews across paginated fetches), date (YYYY-MM-DD), rating (1-5), text (full review text: description plus title when present)
  • Sub-ratings: staffRating, punctualityRating, helpfulnessRating, knowledgeRating
  • Context: author, appointmentType, source (organic = written on RateMDs, partner = collected by a partner)
  • Joins and meta: type (always "review"), doctorName, doctorProfileUrl, runId

Each review links to its doctor via doctorName / doctorProfileUrl; runId isolates items of a single run. On the platform the reviews alias is a run-scoped storage created at run start (fresh for every run), logged as reviewsDatasetId. Fetch it from the run page (Storage tab -> Dataset -> reviews) or with GET /v2/datasets/<reviewsDatasetId>/items.

Fallback: a restricted-token run (LIMITED_PERMISSIONS, e.g. MCP/token runs) that cannot write the second storage logs a warning and writes those reviews into the default dataset marked "type": "review". Start from the Apify Console (full access) for the separate dataset.

Example Input And Output

Example Input — search mode, Toronto dentists

{
"mode": "search",
"location": "on/toronto",
"specialty": "dentist",
"country": "ca",
"maxItems": 50,
"maxPages": 5,
"includeReviews": true,
"maxReviewsPerDoctor": 20,
"proxy": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

Example Output — profile row (default dataset)

{
"name": "Dr. Jane Doe",
"profileUrl": "https://www.ratemds.com/doctor-ratings/dr-jane-doe-toronto-on/",
"specialty": "Family Medicine",
"practiceName": "Toronto Family Clinic",
"city": "Toronto",
"state": "Ontario",
"country": "Canada",
"phone": "(416) 555-0123",
"reviewCount": 42,
"averageScore": 4.6,
"overallRating": 4.6,
"staffRating": 4.5,
"punctualityRating": 4.7,
"helpfulnessRating": 4.6,
"knowledgeRating": 4.8,
"latitude": 43.6532,
"longitude": -79.3832,
"scrapedAt": "2026-10-05T12:34:56.789Z"
}

Example Output — review row (reviews dataset)

{
"id": 9003,
"date": "2024-01-15",
"rating": 5,
"text": "Excellent doctor, very caring...",
"staffRating": 5,
"punctualityRating": 5,
"helpfulnessRating": 5,
"knowledgeRating": 5,
"source": "organic",
"type": "review",
"doctorName": "Dr. Jane Doe",
"doctorProfileUrl": "https://www.ratemds.com/doctor-ratings/dr-jane-doe-toronto-on/",
"runId": "AbCdEf123456"
}

RateMDs Scraper For Apify — Pricing, Performance And Cost

  • Pay-per-event pricing: Doctor $0.0015 per profile (DIAMOND $0.0014), Review $0.00015 per review (DIAMOND $0.00014), Actor Start $0.00005. At the user's maximum charge (ACTOR_MAX_TOTAL_CHARGE_USD) the crawler stops instead of billing more.
  • Free/paid tier: free-tier accounts get 10 profiles per run; paid accounts are unlimited.
  • Memory: 1024 MB default (peak ~330 MB with 6 parallel requests; 256 MB was OOM-killed); 256-4096 MB range, default timeout 3600 s (max 14400 s). Each additional parallel slot parses its own page, so use 1024 MB for 10 slots and 2048 MB for 20.
  • Speed: ~100 profiles in 30-60 seconds with 10 parallel requests (was ~2 minutes with a single request). Slots start together and share a few sessions, so the crawler is not limited by one PoW solve per IP. Review pages after page 1 are fetched in parallel (3 at a time), which mainly speeds up maxReviewsPerDoctor values above 20.
  • Compute: ~0.01-0.05 CU per 100 profiles; CheerioCrawler is 10-20x faster and 4-8x cheaper on Apify compute units than browser automation. Residential bandwidth is required (included in Apify paid plans).

Limitations: residential proxy is an additional cost; free tier limited to 10 profiles per run; partner reviews keep only the fields both lists share (id, date, rating, text, author) — per-item sub-ratings have no organic counterpart and are not guessed; some profile fields may be missing if not present in embedded JSON or JSON-LD.

Anti-Bot Strategy: Residential Proxies And Proof-Of-Work

RateMDs sits behind Cloudflare with a JavaScript proof-of-work challenge, answered without a browser:

  • HTTP 202 proof-of-work: page requests get HTTP 202 plus window.POW_CHALLENGE_DATA = { challenge_nonce, challenge_hmac, difficulty, difficulty_char, issued_at, ... }. The actor solves it like the site's script (SHA-256 over nonce + issued_at + n until the hash starts with difficulty_char repeated difficulty times — difficulty 3 is a few thousand hashes), stores the pow_bypass cookie and refetches in the same session with context.sendRequest.
  • In-session refetch is essential: a solve is only accepted from the sticky proxy IP it was issued to; retrying through Crawlee's queue picks a new IP with a fresh challenge — the failure that previously ended runs with "0 succeeded, 1 failed".
  • HTTP 406 handling: datacenter IPs are rejected outright, so RESIDENTIAL is mandatory. A mid-run 406 usually means the sticky IP went bad: the actor retires the session (Apify hands out a different sticky residential IP), drops the cookie for a fresh challenge and retries; the run aborts after 10 blocked responses. Review pages recover the same way, up to 3 rotations per doctor.
  • Shared sticky sessions: maxConcurrency fills every crawler slot immediately, but at most 3 sticky residential sessions are live (MAX_PROXY_SESSIONS). The first request on a session solves the PoW challenge and the rest reuse its cookie, so solve cost scales with sessions rather than slots. Solves are serialized per session (withSessionLock), so concurrent requests cannot interleave pow_trace / pow_bypass cookie writes.

Data extraction priority: (1) window.DATA.* JSON blobs (doctorDetailProps, ratingsPage) — ratings, reviews, schools, languages, locations, coordinates; (2) JSON-LD (Physician / MedicalWebPage / BreadcrumbList) — address, phone, hours, aggregate rating; (3) DOM — listing cards (.doctor-profile-card) and fallbacks.

Endpoints And Review Pagination

  • Listing pages: https://www.ratemds.com/best-doctors/{state}/{city}/[{specialty-slug}]/?page={N}. Pagination follows <link rel="next"> up to maxPages. There is no country prefix — us/ and ca/ prefixes in the input are stripped automatically.
  • Profile pages: https://www.ratemds.com/doctor-ratings/{slug}/ (also accepts the legacy form /doctor-ratings/{id}/Dr-Name-City-ST.html/).
  • Review pages (organic): https://www.ratemds.com/doctor-ratings/{slug}/?page=N (page 1 is the profile URL itself). The response is an ordinary server-rendered HTML page whose window.DATA.doctorDetailProps.ratingsPage contains that page of the list, so it is parsed with Cheerio. The scraper walks it when the organic count exceeds what the profile embedded, from page 1, deduplicating by id. The embedded widget's total_pages can be wrong (1 page even for a doctor with 525 reviews), so page 1's payload is used to correct it.
  • Review pages (partner): https://www.ratemds.com/doctor-ratings/{slug}/?third_party_page=N. RateMDs splits reviews into two lists; the headline reviewCount is the sum, so doctors with hundreds of ratings and 0-2 organic ones (e.g. 426 partner) would otherwise yield none. The same HTML page embeds doctorDetailProps.thirdPartyRatingsPage; entries use different field names (description, reviewer_name, date_added) and are tagged source: "partner".
  • The internal ?json=true XHR endpoints used by the site's own JavaScript are not called (they are the most aggressively rate-limited part of the site). Both review lists are fetched as plain HTML inside the profile request's session (same sticky IP and solved cookie), up to 10 pages per list per doctor (10 reviews per page).

Integrations & Automation

  • Apify Console: paste an input JSON (see Example Input), select the RESIDENTIAL proxy group, start. Both datasets appear on the run's Output tab.
  • Apify API: start runs with POST https://api.apify.com/v2/acts/LUulX2IdYvMb9dy3V/runs, poll GET /v2/actor-runs/<runId>, then fetch output.profiles and output.reviews.
  • Webhooks: fire on run SUCCEEDED to push output.reviews into your database or review-monitoring pipeline automatically.
  • Zapier / Make: trigger on a new run or dataset item to route reviews into Sheets, Airflow or a CRM.
  • Recommended schedule: run daily or weekly per doctor watchlist (profile mode) or per city/specialty (search mode) for ongoing healthcare review monitoring.

FAQ

Is there an official RateMDs API?

No. RateMDs publishes no public API — no developer portal, no documented endpoint for doctor or review data. To get RateMDs reviews programmatically you need a scraper like this actor, then query its datasets over the Apify API.

What are the alternatives to this actor?

Other RateMDs-focused actors exist in the Apify Store — parseforge's and scrapersdelight's ratemds-scraper, among them. For adjacent physician rating websites, see the Healthgrades, Vitals and Zocdoc scrapers linked in Related Actors; WebMD scrapers are also available in the Store.

Which websites should I monitor for physician reviews?

Reputation-audit guides typically name Healthgrades, Vitals, RateMDs, WebMD, Yelp and Zocdoc as the core physician review platforms. This actor covers the RateMDs slice; pair it with scrapers for the others.

What are the best doctor rating sites?

Commonly compared sites include Healthgrades, Zocdoc, Vitals and RateMDs. RateMDs covers US and Canadian doctors with multi-dimensional ratings (overall, staff, punctuality, helpfulness, knowledge) and patient review text.

How do I build a doctor lead list with ratings?

Use search mode with a location (state or state/city slug) and optional specialty, then read the default dataset: each profile row carries phone, address fields, specialty, reviewCount, averageScore and the five rating dimensions.

SEO Keywords

ratemds scraper, ratemds reviews api, ratemds api, ratemds scraper apify, scrape ratemds.com doctor data, doctor reviews data api, healthcare provider reviews api, physician ratings data, healthcare review monitoring, reputation management for doctors, online reputation management for doctors, patient sentiment analysis, healthcare lead generation, doctor leads with ratings and reviews, provider data enrichment, physician market research, doctor rating sites, physician rating websites, best doctor rating sites, compare doctor reviews, scrape doctor reviews for research dataset, medical practice marketing online reviews, clinic reputation monitoring, best rated doctors in city, doctor ratings near me

For AI Agents & LLM Apps

Purpose: extract doctor profiles and patient reviews from RateMDs.com (US + Canada) into two structured datasets.

Minimal working input:

{
"mode": "search",
"location": "tx/houston",
"proxy": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

Variant — profile mode: {"mode": "profile", "profileUrls": ["https://www.ratemds.com/doctor-ratings/dr-jane-doe-toronto-on/"]}

Output fields: 33 profile fields in the default dataset, 15 review fields in the reviews dataset — full inventory with groupings in the Output Fields section above.

Behaviors an agent should know:

  • mode is the only required field: search (default) crawls listing pages, profile fetches profileUrls directly. US + Canada only (country: us / ca / both, default both); a country prefix in location is stripped automatically.
  • Dual-dataset writes: profiles go to the default dataset, reviews to the separate reviews dataset; both URLs are exposed at output.profiles and output.reviews. If the second storage cannot be written (restricted token), reviews fall back into the default dataset marked "type": "review".
  • includeReviews defaults to true — each stored review is a billed Review event. Cost-relevant defaults if unset: maxItems 100, maxPages 10, maxReviewsPerDoctor 5; 0 means unlimited (capped by Apify limits).
  • maxConcurrency (1-20, default 10) fills parallel slots immediately; those requests share up to 3 sticky residential sessions (PoW solved once per session). The residential proxy is mandatory (datacenter IPs get HTTP 406 and the run fails). Use 1024 MB+ memory for 10+ parallel slots.

Billing (pay-per-event): Doctor $0.0015 per profile (DIAMOND $0.0014) + Review $0.00015 per review (DIAMOND $0.00014) + Actor Start $0.00005.

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by RateMDs or its operators.

It accesses only publicly available RateMDs pages — no login, paywall or authentication bypass. It uses residential proxies and solves the site's public proof-of-work challenge to retrieve those public pages.

You are solely responsible for complying with RateMDs' Terms of Service and applicable data-protection laws (GDPR, CCPA where relevant) when collecting, storing or using the data. Output includes doctor names, practice contact details and patient review content — all publicly posted on RateMDs. Do not use personal contact data for unsolicited commercial outreach in violation of applicable law, and do not represent scraped ratings or reviews as verified medical advice.