# Clinical Trial Sites & Investigators (`dataio/clinical-trial-sites`) Actor

One row per trial SITE, not per trial — with facility, city, country, coordinates and the investigator's name, role, phone and email as published on ClinicalTrials.gov.

- **URL**: https://apify.com/dataio/clinical-trial-sites.md
- **Developed by:** [Tom Awake](https://apify.com/dataio) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$6.00 / 1,000 trial sites

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

## Clinical Trial Sites & Investigators

Export clinical trial **sites** from ClinicalTrials.gov — one row per site,
with the investigator's name, role, phone number and email as published by
the sponsor.

**No login. No API key. No proxies.**

### Why one row per site

Every other tool gives you one row per *trial*, with the sites buried in a
nested field — and the leading alternative states plainly that it does **not
include site contacts or investigator details**.

That is the wrong shape for the people who actually need this data. A CRO
looking for investigators, a site network scouting partners, a patient
recruitment agency, a medical affairs team mapping KOLs — none of them want
a study. They want to know **who to call**.

So this Actor flattens the other way: one row per site, with the contact
attached.

Measured on recruiting breast cancer trials, 200 site rows:

| | Coverage |
|---|---|
| Phone number | **96 %** |
| Email address | **80 %** |
| Coordinates | **100 %** |

Real rows, real institutions — `caroli-bosc.p@chu-nice.fr` at CHU de Nice,
`louis.potier@aphp.fr` at Bichat-Claude Bernard.

### Output

| Field | Example |
|---|---|
| `facility` | Hadassah Medical Center |
| `siteCity`, `siteState`, `siteCountry` | Jerusalem, —, Israel |
| `latitude`, `longitude` | 31.7683, 35.2137 |
| `siteStatus` | RECRUITING |
| `contactName` | Tanir Michal Eloise, MD |
| `contactRole` | CONTACT |
| `contactPhone` | +972 2 677 7111 |
| `contactEmail` | tanir@hadassah.org.il |
| `contactSource` | `site`, `central` or `none` |
| `nctId`, `studyUrl` | NCT01234567 |
| `briefTitle`, `overallStatus`, `phase`, `studyType` | |
| `leadSponsor`, `sponsorClass` | |
| `conditions`, `interventions` | |
| `enrollment`, `startDate`, `completionDate` | |
| `minimumAge`, `sex`, `healthyVolunteers` | |
| `centralContactName`, `centralContactPhone`, `centralContactEmail` | |

`contactSource` tells you where the contact came from. When a site publishes
no contact of its own, the study's central contact is used rather than
leaving the row unreachable — and the field says so, so you can filter if you
only want site-level people.

### Input

```json
{
  "condition": "breast cancer",
  "status": ["RECRUITING"],
  "onlyWithContact": true,
  "maxItems": 500
}
```

| Field | Default | Notes |
|---|---|---|
| `condition` | `breast cancer` | Condition or disease |
| `status` | `["RECRUITING"]` | Nine recruitment statuses |
| `onlyWithContact` | `true` | Keep only rows with a phone or email |
| `maxItems` | `500` | Counts **sites**, not trials |
| `country` | — | Country or city, e.g. `France` |
| `phase` | — | Early Phase 1 through Phase 4 |
| `intervention` | — | Drug or procedure, e.g. `pembrolizumab` |
| `sponsor` | — | Lead sponsor, e.g. `Sanofi` |
| `searchTerm` | — | Free text across the whole record |
| `maxSitesPerStudy` | `0` | Cap sites per trial; `0` means no cap |

**`maxSitesPerStudy` matters more than it looks.** Some phase 3 trials
register hundreds of sites and would fill your entire export from a single
study. Setting it to 2 or 3 spreads the export across many trials — in
testing, 60 rows covered 41 different trials instead of 2.

### Use cases

- **Site selection and feasibility** — find centres already recruiting in
  your indication, with the investigator named.
- **Patient recruitment** — reach the sites actively enrolling, by city.
- **Medical affairs and KOL mapping** — see which investigators run which
  trials, for which sponsor.
- **Competitive intelligence** — which sponsors are running what, where, at
  what enrollment.
- **CRO business development** — a contactable list filtered by indication,
  phase and country.

### Data quality, honestly

This Actor reports exactly what sponsors registered. That means:

- **Coverage varies by phase.** Academic and early-phase trials usually
  publish a named investigator with an institutional email. Large industry
  phase 3 trials often publish a central call centre instead — in testing, a
  phase 3 slice returned 100 % phone numbers but only 2 % emails.
- **Placeholder values exist.** Sponsors sometimes register `111-111-1111`
  or a contact named `Site 034`. These are in the source record; the Actor
  does not silently drop them, so filter if they matter to you.
- **Registered ≠ current.** A site listed as recruiting may have stopped.
  The registry lags reality.

### Personal data

Investigator names, phone numbers and email addresses are personal data.
They are published on a public government registry so that patients and
researchers can make contact **about those trials**.

Using them for unrelated commercial outreach is a different purpose, and in
the EU or UK that makes you the data controller: you need a lawful basis,
you must tell people where their data came from on first contact, and you
must honour objections. That obligation is yours, not the tool's.

### Notes

- Source: the official ClinicalTrials.gov API v2, public and unauthenticated.
- Requests are paced at roughly one per second out of courtesy to a free
  public service.
- Not affiliated with ClinicalTrials.gov, the NIH or the NLM.

# Actor input Schema

## `condition` (type: `string`):

For example "breast cancer", "type 2 diabetes", "Crohn disease".

## `status` (type: `array`):

Leave as Recruiting to reach sites that are actively enrolling — the sites worth contacting.

## `onlyWithContact` (type: `boolean`):

Recommended when building a call or mail list. Sites with no site-level contact fall back to the study's central contact before being judged.

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

One row per site. A single trial can register hundreds of sites, so this counts sites, not trials.

## `country` (type: `string`):

Restrict to a location, for example "France", "Germany" or "Boston".

## `phase` (type: `array`):

Leave empty for every phase. Phase 2 and 3 trials run the most sites, so they yield the longest contact lists.

## `intervention` (type: `string`):

For example "pembrolizumab", "CAR-T", "semaglutide".

## `sponsor` (type: `string`):

Lead sponsor name, for example "Sanofi" or "Mayo Clinic".

## `searchTerm` (type: `string`):

Searched across the whole record when the fields above are not enough.

## `maxSitesPerStudy` (type: `integer`):

Some trials register over a thousand sites and would fill the whole export. 0 means no cap.

## Actor input object example

```json
{
  "condition": "breast cancer",
  "status": [
    "RECRUITING"
  ],
  "onlyWithContact": true,
  "maxItems": 500,
  "maxSitesPerStudy": 0
}
```

# Actor output Schema

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

Every row produced by the run, in JSON.

# 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 = {
    "condition": "breast cancer",
    "status": [
        "RECRUITING"
    ],
    "maxItems": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataio/clinical-trial-sites").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 = {
    "condition": "breast cancer",
    "status": ["RECRUITING"],
    "maxItems": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("dataio/clinical-trial-sites").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 '{
  "condition": "breast cancer",
  "status": [
    "RECRUITING"
  ],
  "maxItems": 500
}' |
apify call dataio/clinical-trial-sites --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataio/clinical-trial-sites"
        }
    }
}
```

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/61628CLsJLRrcIt7o/builds/HKngdmXLNdZJ3J18R/openapi.json
