# Clinical Trials & FDA Drug Data (`miacx/clinical-trials-fda`) Actor

Search ClinicalTrials.gov studies and FDA drug labels, recalls or adverse-event reaction counts. Get structured records from public government APIs.

- **URL**: https://apify.com/miacx/clinical-trials-fda.md
- **Developed by:** [mia.cx](https://apify.com/miacx) (community)
- **Security:** Limited permissions
- **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.

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

## Clinical Trials & FDA Drug Data

Give your agent study records and FDA drug data without parsing government websites.
Search ClinicalTrials.gov studies or openFDA drug labels, recalls and aggregate adverse-event reaction counts.
Each successful Record costs $0.0018, plus $0.00005 per run start at default memory.

### Try it

```json
{"mode":"trials","nctIds":["NCT04280705"]}
```

This looks up one study by ID. An empty input `{}` searches for up to 10 lung-cancer studies.
No upstream API key is required. FDA modes can use an optional caller-supplied `OPENFDA_API_KEY` environment variable.

### Use from an agent

Add `https://mcp.apify.com?tools=miacx/clinical-trials-fda` to your MCP client and sign in to Apify.
Call the dedicated Actor tool, then use `get-dataset-items` to read the completed run's dataset.
Or set `APIFY_TOKEN` to your Apify API token and call the API for JSON rows:

```sh
curl --fail-with-body 'https://api.apify.com/v2/actors/miacx~clinical-trials-fda/run-sync-get-dataset-items' \
  -H "Authorization: Bearer $APIFY_TOKEN" -H 'Content-Type: application/json' \
  -d '{"mode":"trials","nctIds":["NCT04280705"]}'
```

### What you get

Read `status` first. Each `ok` row represents one study, label, recall or aggregate reaction count.
Invalid and missing NCT IDs return separate uncharged rows alongside successful results.
Adverse-event rows count reports mentioning a reaction; they are not individual reports or evidence of incidence or causality.

Selected fields from the recorded ClinicalTrials.gov fixture, normalized with the example input:

```json
{
  "type": "trials",
  "status": "ok",
  "nctId": "NCT04280705",
  "title": "Adaptive COVID-19 Treatment Trial (ACTT)",
  "trialStatus": "COMPLETED",
  "phase": "PHASE3",
  "conditions": "COVID-19",
  "interventions": "Placebo; Remdesivir",
  "sponsor": "National Institute of Allergy and Infectious Diseases (NIAID)",
  "enrollment": 1062,
  "startDate": "2020-02-21",
  "completionDate": "2020-05-21",
  "locationCount": 60,
  "url": "https://clinicaltrials.gov/study/NCT04280705"
}
```

Every row includes `type`, `status`, `input`, `source` and `fetchedAt`.
`input` is normalized JSON, or an individual failed NCT ID. `source` is the upstream query URL without credentials.
`source` is empty when validation or budget prevents fetching. `fetchedAt` marks processing time, even on cache hits.
Failed rows include `reason`; successful rows omit it. Fields for other modes and failed records are absent.

Missing source values are null. Multi-value study and label fields join with semicolons in source order.
Country names remove duplicates. `locationCount` is zero when no location entries are present.
Study dates retain source precision; FDA dates use `YYYYMMDD`.

Label rows include `labelId`, `brandName`, `genericName`, `manufacturer`, `purpose`, `indications`, `warnings`, `dosage` and `effectiveDate`.
Recall rows include `recallNumber`, `product`, `reasonForRecall`, `classification`, `recallStatus`, `recallingFirm`, `recallDate`, `country` and `distribution`.
Adverse-event rows contain `term` and `count`; one report can mention multiple reactions.

### Input

| Field | Default | Accepted input |
| --- | --- | --- |
| `mode` | `"trials"` | `trials`, `drug-labels`, `recalls` or `adverse-events`. |
| `query` | `"lung cancer"` | Trial free text, label generic name, recall product description or adverse-event medicinal product. Empty removes this filter. |
| `condition` | `""` | Trial condition text. Empty applies no filter. |
| `intervention` | `""` | Trial intervention name. Empty applies no filter. |
| `sponsor` | `""` | Trial sponsor text. Empty applies no filter. |
| `trialStatus` | `""` | One status listed below; empty accepts all. |
| `phase` | `""` | `EARLY_PHASE1`, `PHASE1`, `PHASE2`, `PHASE3`, `PHASE4` or `NA`; empty accepts all. |
| `country` | `""` | Exact trial location country, such as `United States`. Empty accepts all. |
| `dateFrom` | `""` | Inclusive lower date, `YYYY-MM-DD`. Empty leaves it open; FDA uses `1900-01-01`. |
| `dateTo` | `""` | Inclusive upper date, `YYYY-MM-DD`. Empty leaves it open; FDA uses `2999-12-31`. |
| `nctIds` | `[]` | Up to 100 strings, trimmed, uppercased and deduplicated. Nonempty overrides trial filters and `limit`. |
| `limit` | `10` | 1–100 first-page records, or top reaction terms by count. No automatic pagination. |

Text fields and individual NCT inputs allow at most 500 characters. Unknown fields are invalid.
Trial statuses are `RECRUITING`, `NOT_YET_RECRUITING`, `ACTIVE_NOT_RECRUITING`, `COMPLETED`, `TERMINATED`, `WITHDRAWN`, `SUSPENDED`, `ENROLLING_BY_INVITATION` and `UNKNOWN`.
Filters use AND. Set `query: ""` to use structured trial filters without the default lung-cancer text.
Trial-only filters are ignored in FDA modes, but supplied status, phase and dates still undergo validation.
Dates filter study start, label effective date, recall initiation date or adverse-event received date. The lower bound cannot exceed the upper.

For FDA labels, use `{"mode":"drug-labels","query":"aspirin","limit":3}`.
Change the mode to `recalls` or `adverse-events` for the other FDA sources.

### Pricing

| Event | Price | Counted unit |
| --- | --- | --- |
| Record | $0.0018 | One `ok` study, label, recall or aggregate reaction-count row, including rows with missing optional fields. |
| Actor start | $0.00005 | One run start at the default 128 MB memory. |

Ten successful records cost $0.01805 including startup at default memory.
NCT input IDs are deduplicated within the run; other results follow the source response.
Cached records still count. Errors and `no_results` rows incur no Record events.
Successful rows remain billable when other rows fail. The spending limit can reduce the successful rows delivered.
The $0.00005 per run start at default memory applies even with no billable records.
Apify counts one startup event per GB of memory, with a minimum of one event.

### Limits and data freshness

- Each run requests one bounded upstream page. If ClinicalTrials.gov rejects a multi-ID request with HTTP 400, each ID is checked once individually, with at most three requests in flight; missing IDs return `no_results`. Search order and source updates affect which records appear.
- Responses are limited to 2 MiB within a 24-second request deadline. Reduce `limit` or the NCT-ID batch if needed.
- Successful responses can be reused for 15 minutes for trials and one hour for FDA data.
- FDA label text can retain HTML and omit harmonized names. Study enrollment can be planned or actual.
- openFDA data is not intended for medical-care decisions. Reaction counts can include duplicate reports.

No runtime LLM calls run. Sources are [ClinicalTrials.gov](https://clinicaltrials.gov/data-api/api) and [openFDA](https://open.fda.gov/terms/).
An optional [openFDA key](https://open.fda.gov/apis/authentication/) raises its daily request allowance.

### If a row fails

| Status | Next step |
| --- | --- |
| `invalid_input` | Check fields and dates. NCT IDs require NCT followed by eight digits. |
| `no_results` | Check the ID or broaden the search. |
| `response_too_large` | Reduce `limit` or split the NCT-ID batch. |
| `dns_error`, `network_error`, `timeout`, `rate_limited`, `upstream_HTTP_CODE` | Read `reason`; retry transient failures later. |
| `invalid_response` | The source omitted an identifier/count or returned an unexpected payload; retain the run ID for reporting. |
| `budget_exhausted` | Raise the spending limit or request fewer records. |
| `internal_error` | Retain the run ID and `reason` when reporting the failure. |

# Actor input Schema

## `mode` (type: `string`):

trials, drug-labels, recalls or adverse-events; default trials. Each successful study, label, recall or aggregate reaction-count row incurs one Record event. Adverse-events returns counts, not individual reports.

## `query` (type: `string`):

Text up to 500 characters; default "lung cancer". Searches trial free text, label generic name, recall product description or adverse-event medicinal product. Empty removes this filter. Set a drug name for FDA modes. Trial filters use AND; nonempty nctIds overrides them.

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

Trial condition text up to 500 characters, such as "type 2 diabetes". Default empty applies no condition filter. Combined with other trial filters using AND; ignored in FDA modes or when nctIds is nonempty.

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

Trial intervention text up to 500 characters, such as "pembrolizumab". Default empty applies no intervention filter. Combined with other trial filters using AND; ignored in FDA modes or when nctIds is nonempty.

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

Trial sponsor text up to 500 characters, such as "National Cancer Institute". Default empty applies no sponsor filter. Combined with other trial filters using AND; ignored in FDA modes or when nctIds is nonempty.

## `trialStatus` (type: `string`):

RECRUITING, NOT_YET_RECRUITING, ACTIVE_NOT_RECRUITING, COMPLETED, TERMINATED, WITHDRAWN, SUSPENDED, ENROLLING_BY_INVITATION or UNKNOWN. Default empty accepts all statuses. Combined with other trial filters using AND. Validated in every mode, but only filters trials without nctIds.

## `phase` (type: `string`):

EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4 or NA. Default empty accepts all phases. Combined with other trial filters using AND. Validated in every mode, but only filters trials without nctIds.

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

Exact ClinicalTrials.gov location country, such as "United States", up to 500 characters. Default empty accepts all countries. Combined with other trial filters using AND; ignored in FDA modes or when nctIds is nonempty.

## `dateFrom` (type: `string`):

Inclusive calendar date YYYY-MM-DD; default empty leaves the lower bound open (FDA uses 1900-01-01). Filters study start, label effective date, recall initiation or adverse-event received date. Must not exceed dateTo. Validated but ignored for trial NCT-ID lookup.

## `dateTo` (type: `string`):

Inclusive calendar date YYYY-MM-DD; default empty leaves the upper bound open (FDA uses 2999-12-31). Filters study start, label effective date, recall initiation or adverse-event received date. Must not precede dateFrom. Validated but ignored for trial NCT-ID lookup.

## `nctIds` (type: `array`):

Up to 100 strings, each at most 500 characters, such as "NCT04280705". Trimmed, uppercased and deduplicated within the run. Default \[] uses search filters. In trials mode a nonempty list overrides filters and limit; invalid or missing IDs return rows without Record charges. Ignored in FDA modes.

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

Integer from 1 to 100; default 10. Caps the first page of studies, labels or recalls, or the top adverse-event reaction terms by count. No automatic pagination. Nonempty nctIds overrides this cap in trials mode. The spending limit can reduce delivered successful rows.

## Actor input object example

```json
{
  "mode": "trials",
  "query": "lung cancer",
  "condition": "",
  "intervention": "",
  "sponsor": "",
  "trialStatus": "",
  "phase": "",
  "country": "",
  "dateFrom": "",
  "dateTo": "",
  "nctIds": [],
  "limit": 10
}
```

# Actor output Schema

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

One row per item, each with a status field.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("miacx/clinical-trials-fda").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("miacx/clinical-trials-fda").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 '{}' |
apify call miacx/clinical-trials-fda --silent --output-dataset

```

## MCP server setup

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

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/Ptn3ztqCe1FKpko67/builds/HE5tESwCJDEjMeJH4/openapi.json
