# CMS Open Payments Scraper (`automation-lab/cms-open-payments-data`) Actor

Search and export official CMS Open Payments physician, hospital, manufacturer, amount, date, payment-nature, program-year, and source records.

- **URL**: https://apify.com/automation-lab/cms-open-payments-data.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## CMS Open Payments Scraper

Search **CMS Open Payments** and export official physician, practitioner, teaching-hospital, manufacturer, amount, date, payment-nature, product, program-year, and source-record data.

The Actor turns bounded searches of the U.S. Centers for Medicare & Medicaid Services (CMS) Open Payments Data API into integration-ready dataset rows.

Use it for Sunshine Act lookup, healthcare compliance review, due diligence, journalism, and repeatable payment-transparency workflows.

### What does CMS Open Payments Scraper do?

The Actor queries official General Payment Data published by CMS.

It can search by:

- physician name;
- exact 10-digit NPI;
- manufacturer or GPO name;
- teaching hospital name;
- recipient state;
- payment nature;
- program year; and
- minimum or maximum payment amount.

Every output item represents an individual CMS payment record, not an inferred match or a generated summary.

The Actor discovers current yearly dataset identifiers from the official CMS catalog, so the default latest-year search advances when CMS publishes a new General Payment Data year.

### Who is it for?

#### Compliance teams

Review transfers of value involving a physician, hospital, or reporting entity and feed selected records into a case-management process.

#### Healthcare due-diligence analysts

Check disclosed industry relationships for a provider or compare records across reporting years.

#### Researchers and journalists

Export source-linked payment rows for reproducible analysis without manually navigating the Open Payments interface.

#### Data and automation teams

Schedule searches, persist datasets, connect webhooks, or load the records into a warehouse or spreadsheet.

### Why use this CMS Open Payments extractor?

- **Official source:** requests go to `openpaymentsdata.cms.gov`.
- **No API key:** the public CMS Data API is queried anonymously.
- **No browser:** direct JSON requests reduce runtime and transfer.
- **Individual records:** results include payer, recipient, amount, date, nature, and record ID.
- **Multi-year input:** search selected program years in one run.
- **Bounded output:** `maxItems` stops collection at the requested limit.
- **Typed dataset:** common CMS field names are normalized for downstream tools.
- **Traceability:** every row includes the CMS dataset ID and source endpoint.

### What CMS Open Payments data can I extract?

| Field | Meaning |
| --- | --- |
| `recordId` | CMS payment record identifier |
| `programYear` | Open Payments reporting year |
| `recipientType` | Physician or teaching-hospital recipient type |
| `recipientProfileId` | CMS recipient profile identifier |
| `recipientNpi` | National Provider Identifier when published |
| `recipientName` | Combined physician or hospital name |
| `recipientSpecialty` | Primary published provider specialty |
| `recipientCity` | Recipient business-address city |
| `recipientState` | Recipient business-address state |
| `manufacturerName` | Manufacturer or GPO making the payment |
| `amountUsd` | Total payment amount in US dollars |
| `paymentDate` | Date of the payment |
| `numberOfPayments` | Transactions represented by the source row |
| `formOfPayment` | Cash, in-kind item, dividend, or another CMS form |
| `natureOfPayment` | Food, consulting, travel, gift, royalty, or another CMS nature |
| `productName` | First associated product, when published |
| `productCategory` | First associated therapeutic/product category |
| `contextualInformation` | Optional context from the reporting entity |
| `disputeStatus` | Whether the record is disputed for publication |
| `sourceDatasetId` | Official yearly CMS dataset identifier |
| `sourceUrl` | Official CMS Data API endpoint |
| `retrievedAt` | UTC retrieval timestamp |

CMS fields can be empty when the source does not publish a value for that payment.

### How to run a physician payment lookup

1. Open the Actor input page.
2. Enter a physician name or exact NPI.
3. Optionally select program years, state, payment nature, or amount bounds.
4. Set the maximum number of records.
5. Click **Start**.
6. Open the default dataset to preview or export the payment rows.

A one-word physician name is treated as an exact last name.

A multi-word name uses the first token as the exact first name and the final token as the exact last name.

For the most precise repeatable match, use an NPI.

### Input parameters

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `physicianName` | string | conditional | One-word last name or first-and-last physician name |
| `npi` | string | conditional | Exact 10-digit NPI |
| `manufacturerName` | string | conditional | Case-insensitive manufacturer/GPO name fragment |
| `teachingHospitalName` | string | conditional | Case-insensitive hospital name fragment |
| `recipientState` | string | no | Two-letter state code |
| `natureOfPayment` | string | no | Exact CMS payment-nature label |
| `programYears` | string\[] | no | Four-digit years from 2019 onward; defaults to latest available |
| `minAmountUsd` | number | no | Inclusive minimum amount |
| `maxAmountUsd` | number | no | Inclusive maximum amount |
| `maxItems` | integer | no | Records to save, from 1 to 10,000; default 100 |

At least one of `physicianName`, `npi`, `manufacturerName`, or `teachingHospitalName` is required.

This requirement prevents accidental unbounded scans of datasets containing millions of records.

### Input examples

#### Search by physician name

```json
{
  "physicianName": "Robert Durick",
  "maxItems": 10
}
```

#### Search by NPI and state

```json
{
  "npi": "1659344299",
  "recipientState": "OH",
  "maxItems": 25
}
```

#### Compare two program years

```json
{
  "npi": "1659344299",
  "programYears": ["2025", "2024"],
  "maxItems": 100
}
```

#### Search manufacturer payments above a threshold

```json
{
  "manufacturerName": "Pfizer",
  "minAmountUsd": 100,
  "programYears": ["2025"],
  "maxItems": 500
}
```

### Output example

The default dataset contains normalized JSON such as:

```json
{
  "recordId": "1157125489",
  "programYear": 2025,
  "recipientType": "Covered Recipient Physician",
  "recipientProfileId": "1235813",
  "recipientNpi": "1659344299",
  "recipientName": "ROBERT DURICK",
  "recipientSpecialty": "Dental Providers|Dentist|General Practice",
  "recipientCity": "YOUNGSTOWN",
  "recipientState": "OH",
  "manufacturerName": "ESSENTIAL DENTAL SYSTEMS INCORPORATED",
  "amountUsd": 47.96,
  "paymentDate": "07/24/2025",
  "numberOfPayments": 1,
  "formOfPayment": "Cash or cash equivalent",
  "natureOfPayment": "Gift",
  "productName": "SafeSider HF",
  "productCategory": "DENTAL",
  "disputeStatus": "No",
  "sourceDatasetId": "fb0b1734-1410-429d-92f6-3f4b35218e5e",
  "sourceUrl": "https://openpaymentsdata.cms.gov/api/1/datastore/query/fb0b1734-1410-429d-92f6-3f4b35218e5e/0",
  "retrievedAt": "2026-08-14T20:11:03.056Z"
}
```

This example reflects current official data. CMS may revise source records in later publications.

### How much does it cost to search CMS Open Payments?

Pricing uses one one-time `start` charge and one `item` charge per saved payment row.

On the Bronze tier, the start charge is **$0.005 per run** and each saved item is **$0.0096**.

Example Bronze prices:

| Saved records | Estimated Actor charge |
| ---: | ---: |
| 1 | $0.0146 |
| 10 | $0.1010 |
| 100 | $0.9650 |
| 1,000 | $9.6050 |

Higher subscription tiers receive lower per-item prices according to the active Apify pricing table.

No item charge is emitted for duplicate, malformed, or rejected source rows.

Apify platform usage may be shown separately according to your plan.

### Scheduling compliance monitoring

Create an Apify Schedule with a stable NPI or company search.

For year-over-year review:

1. keep a versioned copy of each run dataset;
2. use a consistent NPI or exact physician identity;
3. include the relevant program years;
4. compare on `recordId` and source fields; and
5. treat CMS corrections as source revisions, not automatically as new payments.

The Actor does not maintain a private historical database or send alerts itself.

Use Apify webhooks, integrations, or your own workflow to react to completed runs.

### Export and integration workflows

You can export the default dataset as JSON, JSONL, CSV, XML, RSS, or Excel through Apify dataset endpoints.

Common workflows include:

- append NPI-specific rows to a compliance warehouse;
- send high-value payment rows to a review queue;
- compare selected program-year exports in a notebook;
- load manufacturer results into a spreadsheet;
- trigger a webhook after a scheduled run; or
- retrieve output from Make, Zapier, n8n, or another integration.

Use `recordId` as the source identifier and retain `programYear` plus `sourceDatasetId` for audit context.

### Run with the Apify API using cURL

Replace `YOUR_TOKEN` with your Apify API token.

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~cms-open-payments-data/runs?token=YOUR_TOKEN&waitForFinish=120" \
  -H "Content-Type: application/json" \
  -d '{"npi":"1659344299","maxItems":10}'
```

Fetch dataset items using the `defaultDatasetId` returned by the run API.

### Run with JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('automation-lab/cms-open-payments-data').call({
  npi: '1659344299',
  programYears: ['2025', '2024'],
  maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Run with Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation-lab/cms-open-payments-data").call(
    run_input={"physicianName": "Robert Durick", "maxItems": 10}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Apify MCP server to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/cms-open-payments-data"
```

**Claude Desktop setup**

**Cursor setup**

**VS Code setup**

Each client can use the same remote MCP server configuration (place it in the configuration location required by that client):

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/cms-open-payments-data"
    }
  }
}
```

Example prompts:

- “Search CMS Open Payments for NPI 1659344299 and return the ten newest available payment rows.”
- “Export this physician's 2024 and 2025 CMS payment records for a compliance review.”
- “Find CMS General Payment Data for this manufacturer above $500 and summarize it in a table.”

Verify sensitive compliance conclusions against the linked official CMS record and your organization's policies.

### Limits and source behavior

CMS publishes General Payment Data by program year and can correct records in later publication cycles.

The Actor supports program years present in the live CMS catalog, currently from 2019 onward.

Results follow the order returned by the official API; they are not claimed to be sorted by amount or date.

A name search is exact on parsed first/last tokens, while manufacturer and hospital searches use name fragments.

Very broad manufacturer or hospital fragments may take longer than precise NPI or physician queries.

The Actor retries transient network, HTTP 429, and server failures with bounded backoff.

Malformed input, unavailable program years, stable client errors, and invalid CMS response shapes fail the run rather than silently returning misleading empty output.

A valid query with no matching source records succeeds with an empty dataset.

### Data quality and interpretation

Open Payments reports transfers of value submitted under federal program rules.

A listed payment does not by itself establish misconduct, bias, or a financial conflict.

Names can collide, addresses can change, and some fields can be absent.

Prefer NPI or CMS profile identifiers for identity-sensitive work.

Preserve source IDs and timestamps when using records as compliance evidence.

Consult CMS documentation and qualified legal or compliance professionals for interpretation requirements.

### Responsible use

The Actor accesses public U.S. government data without bypassing access controls.

You are responsible for lawful use, retention, sharing, and interpretation of the output.

Do not use payment data as the sole basis for an adverse employment, credentialing, insurance, healthcare, or legal decision.

Follow applicable privacy, anti-discrimination, due-process, and records-management obligations.

### Troubleshooting

#### Why did my run return no records?

Check spelling, NPI, selected year, state, amount bounds, and exact payment-nature label.

Try an NPI-only search to reduce name ambiguity.

Remember that omission of `programYears` searches only the latest available General Payment Data year.

#### Why was my input rejected?

At least one primary search field is required.

NPI must have exactly ten digits, state must have two letters, years must have four digits, and amount bounds cannot be negative or reversed.

#### Why did a CMS request retry?

The public CMS API can respond slowly or transiently fail.

The Actor retries a bounded number of times and logs concise reasons; persistent failures correctly fail the run.

#### Why do two years have different fields or values?

CMS publication content can evolve and reporting entities can submit corrections.

The Actor normalizes a stable subset and leaves unavailable values as `null`.

### FAQ

#### Does the Actor need a CMS API key?

No. It uses public official endpoints.

#### Does it use a proxy or browser?

No. It makes direct JSON requests and has no automatic paid-proxy fallback.

#### Does it include research and ownership payments?

No. This release searches individual **General Payment Data** records. Research and ownership datasets are outside the current contract.

#### Can it search by NPI?

Yes. NPI is the most precise supported provider input.

#### Can I search several years?

Yes. Supply `programYears` as four-digit strings, for example `["2025", "2024"]`.

#### Can it monitor changes automatically?

Schedule repeated Actor runs and compare stored datasets or use a webhook. The Actor extracts records but does not itself retain history or issue alerts.

#### Is this medical or legal advice?

No. It supplies public records for analysis and does not provide medical, legal, or compliance conclusions.

### Related automation-lab Actors

For adjacent public-data workflows, explore the [automation-lab Actor portfolio](https://apify.com/automation-lab).

Only use related Actors whose source and output contract match your actual workflow; CMS Open Payments records are not a substitute for licensing, sanctions, clinical, or credential data.

### Support

If a run fails unexpectedly, include the run URL, a redacted input, the affected program year, and whether the same query works on the official CMS Open Payments site.

Do not include Apify tokens, private case notes, or unrelated personal information in a support report.

# Actor input Schema

## `physicianName` (type: `string`):

Physician name. One word matches last name; multiple words match first and last name exactly (for example, Robert Durick).

## `npi` (type: `string`):

Exact 10-digit physician NPI. Can be used alone or with other filters.

## `manufacturerName` (type: `string`):

Case-insensitive company-name fragment, such as Pfizer.

## `teachingHospitalName` (type: `string`):

Case-insensitive teaching-hospital name fragment.

## `recipientState` (type: `string`):

Optional two-letter US state code for the recipient's business address.

## `natureOfPayment` (type: `string`):

Optional exact CMS payment-nature label, such as Food and Beverage.

## `programYears` (type: `array`):

CMS program years to search, newest first. Omit to search the latest available General Payment Data year.

## `minAmountUsd` (type: `number`):

Optional inclusive minimum payment amount.

## `maxAmountUsd` (type: `number`):

Optional inclusive maximum payment amount.

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

Maximum individual payment records to save across all selected years.

## Actor input object example

```json
{
  "physicianName": "Robert Durick",
  "maxItems": 10
}
```

# Actor output Schema

## `overview` (type: `string`):

Default dataset containing normalized recipient, manufacturer, amount, date, payment nature, program year, and CMS source fields.

# 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 = {
    "physicianName": "Robert Durick",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/cms-open-payments-data").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 = {
    "physicianName": "Robert Durick",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/cms-open-payments-data").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 '{
  "physicianName": "Robert Durick",
  "maxItems": 10
}' |
apify call automation-lab/cms-open-payments-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/cms-open-payments-data"
        }
    }
}

```

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/bet9wvGaP3pl1xr7I/builds/Qg9kQtEtbyrdssNH1/openapi.json
