# CMS Provider Facilities Scraper (Medicare) (`devilscrapes/cms-provider-facilities-scraper`) Actor

Bulk-export US Medicare-certified healthcare facilities — nursing homes, hospitals, home health agencies, hospices — from the official CMS Provider Data Catalog. Filter by state or city; quality and star-rating columns included. No login, no API key.

- **URL**: https://apify.com/devilscrapes/cms-provider-facilities-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

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

<div align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />

## CMS Provider Facilities Scraper (Medicare)

**$4.00 / 1 000 results**  ·  pay only for results  ·  no credit card to try

*We do the dirty work so your dataset stays clean.* 😈

Turn the federal CMS Provider Data Catalog into a clean, filtered facility dataset. Query nursing homes, hospitals, home health agencies, or hospices by state or city and get back structured, Pydantic-validated rows with address, phone, and every quality/star-rating column CMS publishes.

</div>

***

### 🎯 What this scrapes

The **CMS Provider Data Catalog** (data.cms.gov/provider-data) is the federal government's authoritative directory of every Medicare-certified healthcare facility in the country — nursing homes, hospitals, home health agencies, and hospices — complete with address, phone, ownership, staffing, and the CMS 1-5 star quality ratings that drive Medicare's own "Care Compare" tool.

The catalog's own datastore-query API is public, but turning it into a reliable bulk export takes real engineering: each facility type publishes a *different* column set (a hospital record and a nursing-home record share almost no field names), the national datasets run past 450 000 rows, and a naive client either downloads entire CSVs or has to reverse-engineer the datastore's bracketed `conditions[]` filter syntax to query server-side. We did that reverse-engineering, curated four facility datasets behind one friendly `dataset` input, and hand you back one richly-typed row per facility — core columns normalised, everything else preserved in a typed `extras` map.

Sales teams, ESG analysts, and healthcare-data resellers currently stitch this together from 25+ single-dataset scrapers or hand-rolled CSV downloads. This Actor unifies all four facility types behind one input schema, with server-side state/city filtering so you never pay to transfer rows you didn't ask for.

### 🔥 What we handle for you

- 🔁 **Real limit/offset pagination** — the datastore API caps nothing on paper, but we page in bounded 500-row chunks and stop exactly when the server-reported match count is reached, so a broad query doesn't run away.
- 🛡️ **Retry with exponential backoff** — on `408 / 429 / 5xx` we back off (2s → 30s, capped) and honour `Retry-After`, up to 5 attempts per page, before surfacing an error.
- 🧊 **Per-item fault isolation** — one malformed record in a page of 500 is logged and skipped; it never sinks the rest of the page.
- 🧱 **Pydantic-validated rows** — a stable core (CCN, name, address, city, state, ZIP, phone) plus a typed `extras` map for every dataset-specific column (star ratings, ownership, bed counts, services offered). Nothing degrades to a bare, untyped dict.
- 🌐 **Proxy-ready** — data.cms.gov is a public federal endpoint and direct routing works on most infrastructure; the Apify Proxy field is there when your network needs it.
- 💰 **You pay only for results that land.** No data → no charge beyond the small run warm-up fee.

### 💡 Use cases

- **Healthcare vendor sales lists** — pull every nursing home or hospital in a state for a targeted outreach or prospecting list.
- **ESG / site-diligence screening** — check quality ratings, ownership type, and inspection history before an acquisition or partnership.
- **Compliance & referral-network products** — bulk-export by facility type and resell structured datasets to billing, credentialing, or referral tools.
- **Journalism & policy research** — analyze facility quality, ownership concentration, or staffing trends by state.
- **Competitive intelligence** — track how a chain's facilities rank across the CMS star-rating system.
- **Home health / hospice referral sourcing** — build a state-scoped directory of agencies with services offered and quality scores.

### ⚙️ How to use it

1. Click **Try for free** — no credit card required.
2. Pick a **dataset**: `nursing_homes`, `hospitals`, `home_health_agencies`, or `hospices`.
3. Optionally set **state** and/or **city** — both are filtered server-side by CMS, so narrower is cheaper.
4. Set **maxResults** — default 100, hard cap 5000 per run.
5. Click **Start**. Results stream into the dataset in real time.
6. Export from **Storage → Dataset** as JSON, CSV, or Excel.

### 📥 Input

| Field | Type | Required | Default | Notes |
|---|---|:--:|---|---|
| `dataset` | `string` | no | `nursing_homes` | `nursing_homes`, `hospitals`, `home_health_agencies`, or `hospices`. |
| `state` | `string` | no | — | 2-letter state code (CA, NY, TX …). Filtered server-side by CMS. |
| `city` | `string` | no | — | City name within the chosen state, filtered server-side. |
| `maxResults` | `integer` | no | `100` | Max facility records to return (1–5000). |
| `proxyConfiguration` | `object` | no | `{"useApifyProxy": false}` | Apify Proxy settings. Direct routing works for data.cms.gov on most infrastructure. |

#### Example input

```json
{
  "dataset": "nursing_homes",
  "state": "CA",
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

### 📤 Output

Every row is one CMS-certified facility record. Dataset-specific columns (star ratings, ownership, services, staffing) live in `extras`, keyed by their raw CMS field name.

| Field | Type | Notes |
|---|---|---|
| `dataset` | `string` | Which curated dataset this record came from. |
| `ccn` | `string` | CMS Certification Number (or CMS facility ID for hospitals). |
| `name` | `string` | Facility legal/display name. |
| `address` | `string \| null` | Street address. |
| `city` | `string \| null` | City. |
| `state` | `string \| null` | 2-letter state code. |
| `zip_code` | `string \| null` | ZIP code. |
| `phone` | `string \| null` | Telephone number. |
| `extras` | `object` | Every dataset-specific column (ratings, ownership, bed counts, services …), string-valued or `null`. |
| `scraped_at` | `string` | When this row was recorded (ISO-8601 UTC). |

#### Example output

```json
{
  "dataset": "nursing_homes",
  "ccn": "015009",
  "name": "BURNS NURSING HOME, INC.",
  "address": "701 MONROE STREET NW",
  "city": "RUSSELLVILLE",
  "state": "AL",
  "zip_code": "35653",
  "phone": "2563324110",
  "extras": {
    "overall_rating": "2",
    "ownership_type": "For profit - Corporation",
    "number_of_certified_beds": "57"
  },
  "scraped_at": "2026-08-26T00:00:00+00:00"
}
```

### 💰 Pricing

Pay-Per-Event — you only pay when these events fire:

| Event | USD | What triggers it |
|---|---:|---|
| `actor-start` | $0.20 | One-off warm-up charge per run |
| `result-row` | $0.004 | Per facility record written to the dataset |

Example: 1 000 facility records at the rates above = **$4.00** plus the $0.20 run warm-up. No subscription, no minimum, no card required to start — Apify gives every new account free credit.

### 🚧 Limitations

- **Column sets differ per dataset** — a hospital record and a nursing-home record share almost no raw field names. The stable core (CCN, name, address, city, state, ZIP, phone) is normalised; everything else lands in `extras` under its original CMS field name, which varies by `dataset`.
- **No email addresses** — the Provider Data Catalog does not publish facility email addresses. Phone is included; email is not part of the public catalog.
- **US facilities only** — the catalog covers Medicare-certified US facilities. International facilities are out of scope.
- **Data freshness** — CMS refreshes each dataset on its own cadence (often quarterly for quality ratings). The `scraped_at` field marks when the Actor pulled it, not when CMS last updated the underlying record.
- **5000-result hard cap per run** — for a full-state pull larger than that, split by city or run multiple jobs and merge the datasets.

### ❓ FAQ

**Is this data public and legal to use?**

Yes. The CMS Provider Data Catalog is a public federal dataset maintained by the Centers for Medicare & Medicaid Services, published under an open-data policy with no restrictions on use. This Actor queries the public datastore-query API documented at data.cms.gov/provider-data.

**Why do the columns look different for hospitals vs. nursing homes?**

CMS publishes each facility type as an independently maintained dataset with its own column set — a byproduct of decades of separate reporting programs (Nursing Home Compare, Hospital Compare, Home Health Compare, Hospice Compare) being consolidated under one catalog. This Actor normalises the columns every dataset shares (name, address, city, state, ZIP, phone) and preserves the rest in `extras` exactly as CMS names them.

**How current is the data?**

It depends on the dataset — CMS refreshes nursing-home and hospital quality ratings roughly quarterly; core facility listing data (address, phone) updates more often. Every dataset carries a `processing_date`-style field inside `extras` when CMS publishes one.

**Can I filter by ZIP code or facility name?**

Not server-side today — the datastore-query API's server-side filtering is verified for `state` and `city`. Filter by ZIP or name in your own pipeline after export, or open a feature request.

**What does the CMS star rating mean?**

CMS assigns a 1-5 star `overall_rating` (and category sub-ratings for health inspections, staffing, and quality measures) to nursing homes as part of its public Care Compare program. This Actor surfaces those ratings unmodified inside `extras` for the `nursing_homes` dataset.

### 💬 Your feedback

Spotted a bug, need a new facility dataset added, or want ZIP-code filtering built in? Open an issue on the **Issues** tab in Apify Console — we read every report and ship fixes weekly.

***

<div align="center">

Built by **[Devil Scrapes](https://apify.com/DevilScrapes)** 😈 — a small fleet of
opinionated public-data Actors. Honest pricing, real engineering, zero fine print.

</div>

### 🔗 Related Devil Scrapes Actors

Building a healthcare dataset? This sibling pulls individual provider records from the same federal agency:

- [NPI Healthcare Provider Scraper (NPPES)](https://apify.com/DevilScrapes/npi-healthcare-provider-scraper) — individual doctors, dentists, and specialists from the CMS NPI registry

Browse the full fleet at [apify.com/DevilScrapes](https://apify.com/DevilScrapes).

# Actor input Schema

## `dataset` (type: `string`):

Which curated CMS Provider Data Catalog facility dataset to query.

## `state` (type: `string`):

Two-letter US state abbreviation (e.g. <code>CA</code>, <code>NY</code>, <code>TX</code>). Filtered server-side by CMS — narrows the query before it ever leaves their datastore.

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

City name to narrow results within the chosen state (e.g. <code>Los Angeles</code>).

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

Maximum number of facility records to return. Hard cap 5000 per run — split by state for bigger pulls.

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

Apify Proxy settings. data.cms.gov is a public federal open-data API; direct routing is fine for most runs. Enable proxy if your network or the API enforces stricter rate limits.

## Actor input object example

```json
{
  "dataset": "nursing_homes",
  "state": "CA",
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Full set of scraped facility records. Streamed JSON via the Apify dataset API.

## `datasetItemsCsv` (type: `string`):

Same data, CSV export. Drop straight into a spreadsheet or CRM loader.

## `datasetView` (type: `string`):

Open the run's dataset in the Console with the Overview view applied.

# 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 = {
    "dataset": "nursing_homes",
    "state": "CA",
    "maxResults": 5,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/cms-provider-facilities-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 = {
    "dataset": "nursing_homes",
    "state": "CA",
    "maxResults": 5,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/cms-provider-facilities-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 '{
  "dataset": "nursing_homes",
  "state": "CA",
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call devilscrapes/cms-provider-facilities-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/cms-provider-facilities-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/O9bx8S2GDvbeGISRn/builds/I88HGnYkfEUnRdAGl/openapi.json
