# CMS Open Payments Lookup + NPI Enrichment (Sunshine Act) (`sovereign_workspace/cms-open-payments-monitor`) Actor

Look up CMS Open Payments (Sunshine Act) records with optional NPI enrichment (taxonomy code only). Annual CMS data — use as lookup/audit, not a daily monitor.

- **URL**: https://apify.com/sovereign\_workspace/cms-open-payments-monitor.md
- **Developed by:** [Chase Mariano](https://apify.com/sovereign_workspace) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 payment matcheds

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

## CMS Open Payments Lookup + NPI Enrichment (Sunshine Act)

One **event per payment record** from CMS Open Payments, the Sunshine Act
database of payments from drug and device makers to physicians, other
practitioners and teaching hospitals. Filter by manufacturer, recipient
NPI list, state, specialty, program year and minimum amount. Each
record is joined to the **NPPES NPI registry**, so you get the
recipient's *current* taxonomy code, practice address and phone next to what
the manufacturer reported. It's built for compliance audits,
conflict-of-interest reviews, litigation research and KOL mapping.
It's a lookup, not a data dump.

**Pricing: pay per event.** `payment-matched`: $0.03 per payment record
returned. Zero matches costs you nothing.

### Input

```json
{"dataset": "general", "manufacturer": "medtronic", "state": "CA",
 "min_amount": 1000, "limit": 200}
```

Give at least one of `manufacturer`, `npis`, `state` or `specialty`.
Leave `program_year` empty for the latest published year. Set
`dataset` to `research` for research payments; those records carry the
study name and ClinicalTrials.gov ID.

### Example output (one dataset item per payment)

```json
{"dataset": "general", "program_year": 2025, "record_id": "1212037411",
 "change_type": "NEW", "payment_date": "2025-06-27", "amount_usd": 36.0,
 "number_of_payments": 1, "nature_of_payment": "Education",
 "form_of_payment": "In-kind items and services",
 "manufacturer": "Medtronic, Inc.", "manufacturer_id": "100000000106",
 "recipient_type": "Covered Recipient Non-Physician Practitioner",
 "recipient_npi": "1528536174", "recipient_name": "BRIANA GWALTNEY",
 "recipient_specialty": "Physician Assistants & Advanced Practice Nursing Providers|Nurse Practitioner|Family",
 "recipient_city": "Brattleboro", "recipient_state": "VT", "recipient_zip": "05301",
 "products": ["INTERSTIM"], "study_name": null, "clinicaltrials_gov_id": null,
 "dispute_status": "No", "publication_date": "2026-06-30",
 "npi_status": "A",
 "npi_taxonomy_code": "363LF0000X", "npi_address": "100 WASON AVE STE 120",
 "npi_city": "SPRINGFIELD", "npi_state": "MA", "npi_zip": "01107",
 "npi_phone": "413-241-2100"}
```

In that record the payment was reported in Vermont, but NPPES shows the
provider now practicing in Massachusetts. That gap is what the join is for.

### Output fields

One dataset item per result. Every field is always present (empty or null
when the source has no value). The fields are defined in
`.actor/dataset_schema.json`.

| Field | Type | Description |
|---|---|---|
| `dataset` | string | general or research payments |
| `program_year` | integer | Open Payments program year |
| `record_id` | string | CMS Open Payments record ID |
| `change_type` | string | CMS change type (NEW, CHANGED, UNCHANGED, ADDED) |
| `payment_date` | string | Date of payment, YYYY-MM-DD |
| `amount_usd` | number | Total amount of payment, USD |
| `number_of_payments` | integer | Number of payments in the total (general only) |
| `nature_of_payment` | string | Nature of payment, e.g. Food and Beverage, Consulting Fee (general only) |
| `form_of_payment` | string | Form of payment or transfer of value |
| `manufacturer` | string | Applicable manufacturer or GPO making the payment |
| `manufacturer_id` | string | CMS ID of the manufacturer or GPO |
| `recipient_type` | string | Covered recipient type (physician, NPP, teaching hospital) |
| `recipient_npi` | string | Covered recipient NPI (research: principal investigator 1 when blank) |
| `recipient_name` | string | Recipient name as reported to CMS |
| `recipient_specialty` | string | Primary specialty string **as published by CMS** Open Payments (source: CMS; not edited) |
| `recipient_city` | string | Recipient city as reported to CMS |
| `recipient_state` | string | Recipient state as reported to CMS |
| `recipient_zip` | string | Recipient ZIP (5 digits) |
| `products` | array | Related drugs, biologicals, devices or supplies (up to 5) |
| `study_name` | string | Research study name (research only, max 500 chars) |
| `clinicaltrials_gov_id` | string | ClinicalTrials.gov identifier (research only) |
| `dispute_status` | string | Whether the record is disputed for publication |
| `publication_date` | string | CMS publication date, YYYY-MM-DD |
| `npi_status` | string | NPPES: enumeration status (A = active) |
| `npi_taxonomy_code` | string | NPPES: primary taxonomy code |

The NPPES join outputs the taxonomy **code** only. Code descriptions come
from the NUCC Health Care Provider Taxonomy code set, which NUCC licenses for
commercial use, so this Actor doesn't output them. `recipient_specialty` is
the specialty string exactly as CMS publishes it in Open Payments, credited to
CMS.
| `npi_address` | string | NPPES: practice location address |
| `npi_city` | string | NPPES: practice location city |
| `npi_state` | string | NPPES: practice location state |
| `npi_zip` | string | NPPES: practice location ZIP (5 digits) |
| `npi_phone` | string | NPPES: practice location phone |

Runs stop cleanly at your max-charge limit, so nothing is pushed past
what you agreed to pay for. If an NPI isn't in NPPES, its `npi_*` fields
are empty and the payment is still returned. If CMS renames a column the
run fails loudly (`schema:` in the status message) rather than
returning half-empty records.

### About the data

CMS publishes each program year's data by June 30 of the following year
and refreshes it in January. Payments are what reporting manufacturers
and GPOs attested to. In CMS's words: "CMS does not comment on what
relationships may be beneficial or potential conflicts of interest. CMS
publishes the data attested to by reporting entities. The data is open
to individual interpretation." A payment record doesn't by itself show an
improper relationship. Check `dispute_status` before relying on a record.

Need provider records without payments? Try
[NPI Provider Lookup & Enrichment](https://apify.com/sovereign_workspace/npi-provider-lookup).

Source: CMS Open Payments datastore API (public, U.S. government work)
and the CMS NPPES NPI Registry API v2.1 (public).

# Actor input Schema

## `profile` (type: `string`):

Named config preset applied at start. Any field you set explicitly below overrides the preset.

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

Which Open Payments dataset to search: general (non-research) payments or research payments.

## `program_year` (type: `integer`):

Open Payments program year (the year the payment was made). Leave empty for the latest published year. CMS publishes each year's data by June 30 of the following year and refreshes it in January.

## `manufacturer` (type: `string`):

Only payments made by a manufacturer or GPO whose name contains this text (case-insensitive, e.g. pfizer, medtronic).

## `npis` (type: `array`):

Only payments to these physicians or practitioners (up to 200 NPIs), e.g. your KOL list or an audit roster.

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

Only payments to recipients in this US state (e.g. CA, TX).

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

Only payments to recipients whose primary specialty contains this text (e.g. Cardiovascular, Orthopaedic, Dermatology).

## `min_amount` (type: `number`):

Skip payments below this amount (e.g. 1000 to leave out meals). You are only charged for payments at or above it.

## `enrich_npi` (type: `boolean`):

Add each recipient's current NPPES registry taxonomy, practice address and phone. If an NPI isn't found, those fields are left empty; the payment is still returned.

## `limit` (type: `integer`):

Maximum number of payment records to return per run (1-5000).

## Actor input object example

```json
{
  "dataset": "general",
  "manufacturer": "pfizer",
  "state": "VT",
  "enrich_npi": true,
  "limit": 100
}
```

# Actor output Schema

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

No description

## `errorCounters` (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 = {
    "manufacturer": "pfizer",
    "state": "VT"
};

// Run the Actor and wait for it to finish
const run = await client.actor("sovereign_workspace/cms-open-payments-monitor").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 = {
    "manufacturer": "pfizer",
    "state": "VT",
}

# Run the Actor and wait for it to finish
run = client.actor("sovereign_workspace/cms-open-payments-monitor").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 '{
  "manufacturer": "pfizer",
  "state": "VT"
}' |
apify call sovereign_workspace/cms-open-payments-monitor --silent --output-dataset

```

## MCP server setup

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

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/aF7B4p1ETfx5Uiu6I/builds/NJuwvsoeuJvaXW5el/openapi.json
