# Research Papers, PubMed & Clinical Trials Search (no key) (`datawharf-tools/research-search`) Actor

Search Crossref papers, PubMed citations and ClinicalTrials.gov studies in one run. No API key. Flat rows with DOI, PMID or NCT id, title, authors, journal or sponsor, date, phase, status and link. Metadata only, no abstracts. Not affiliated with Crossref, NLM or NIH.

- **URL**: https://apify.com/datawharf-tools/research-search.md
- **Developed by:** [Datawharf Tools](https://apify.com/datawharf-tools) (community)
- **Categories:** Developer tools, Automation, Other
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 results

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

## Research Papers, PubMed & Clinical Trials Search (no API key)

Search **Crossref** (scholarly papers), **PubMed** (biomedical citations) and **ClinicalTrials.gov** (clinical studies) from one form, and get one flat, normalized table you can export to JSON, CSV or Excel. It only calls the three official public APIs (no scraping, no proxies, no login). **No API key and no sign-up.**

**Not affiliated with, endorsed by or sponsored by Crossref, the U.S. National Library of Medicine (NLM), the National Institutes of Health (NIH) or ClinicalTrials.gov.**

### Who is this for?

- **Students, clinicians and analysts** who want a quick literature + trials sweep on a drug, gene or condition.
- **AI-agent and automation builders** who want a single tool that returns IDs and links (DOI, PMID, NCT number) for follow-up.
- **Biotech and market researchers** tracking which sponsors run trials in a phase or status, with recent papers beside them.

### What you get

One row per record, same columns for every source:

`source`, `id` (DOI, PMID or NCT number), `idType`, `title`, `authors` (first N, default 5), `authorCount`, `journal` (papers, PubMed), `sponsor` (trials), `date`, `year`, `type` (work type, publication type or study type), `phase` and `status` (trials), `url`, plus `doi`, `pmid`, `nctId`, `publisher`, `citedByCount` (Crossref), `publicationTypes` (PubMed), `conditions`, `interventions`, `enrollment` and `lastUpdatedByClinicalTrialsGov` (trials), `attribution` and `fetchedAt`.

### Abstracts are NOT returned (on purpose)

Crossref notes that some abstracts "may be subject to copyright by publishers or authors", and NLM states it does not claim copyright in PubMed abstracts but publishers or authors may. To stay clearly on the safe side this Actor returns **citation metadata and links only** and never calls the PubMed abstract endpoint. Each PubMed row links to its PubMed page where the abstract can be read.

### Quick test (default input)

```json
{ "mode": "all", "query": "CRISPR gene therapy", "maxResultsPerSource": 5 }
```

Leaving the input empty runs the same search. It returns up to 15 rows from three sources.

### Inputs

- **mode**: `all`, `papers` (Crossref), `pubmed` or `clinicalTrials`.
- **query**: free text. PubMed accepts PubMed syntax.
- **dateFrom / dateTo** (YYYY-MM-DD): publication date for papers and PubMed, study start date for trials.
- **maxResultsPerSource**: rows from each source (default 5, max 10,000; PubMed returns at most 9,999 per search).
- **maxAuthors**: authors listed per paper.
- **journal**: restrict papers and PubMed to a journal. PubMed matches the journal exactly; Crossref matches journal names loosely ("Nature" also returns "Nature India" or "Nature Machine Intelligence"), so check the `journal` column.
- **crossrefType**: e.g. `journal-article`, `proceedings-article`, `posted-content`.
- **condition, trialStatus, trialPhase**: trial filters (for example `RECRUITING`, `PHASE3`).
- **maxApiCalls**: safety limit on requests (default 100).

### Example inputs

Recruiting phase 2/3 diabetes trials started since 2024, trials only:

```json
{ "mode": "clinicalTrials", "condition": "type 2 diabetes", "trialStatus": ["RECRUITING"], "trialPhase": ["PHASE2", "PHASE3"], "dateFrom": "2024-01-01", "maxResultsPerSource": 50 }
```

Recent PubMed papers in one journal:

```json
{ "mode": "pubmed", "query": "semaglutide", "journal": "Nature Medicine", "dateFrom": "2025-01-01", "maxResultsPerSource": 100 }
```

Crossref journal articles only:

```json
{ "mode": "papers", "query": "graphene battery", "crossrefType": "journal-article", "maxResultsPerSource": 200 }
```

### Good to know

- **Rate limits.** Requests to NCBI are paced to at most 3 per second (the documented limit without a key) and every retry is paced too. Crossref requests identify the project with a contact address (the "polite pool"), and NCBI requests send `tool` and `email` parameters, as both services ask. The contact is datawharf@gmail.com.
- **A failing source does not stop the others** in `all` mode. Check `RUN_REPORT` for per-source counts, API calls, retries and any source errors.
- **PubMed data** is courtesy of the U.S. National Library of Medicine and may not be the most current NLM data. **ClinicalTrials.gov records** are submitted by study sponsors; always open the linked record before relying on it. Each trial row carries `lastUpdatedByClinicalTrialsGov` (the date ClinicalTrials.gov last posted an update for that study) and `fetchedAt`; re-run to keep data current. **Modifications:** records are reformatted into flat rows, only the listed fields are kept, and author lists are shortened to the first N names; no values are otherwise changed. Contact details are not collected. ClinicalTrials.gov is a United States Government database; we claim no rights in it. Crossref metadata is used under Crossref's open metadata policy.
- Not medical advice.

### Use it from code (JavaScript and Python)

JavaScript (`npm install apify-client`):

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('datawharf-tools/research-search').call({ mode: "all", query: "CRISPR gene therapy", maxResultsPerSource: 10 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'rows');
```

Python (`pip install "apify-client>=3"`):

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("datawharf-tools/research-search").call(run_input={"mode": "all", "query": "CRISPR gene therapy", "maxResultsPerSource": 10})
items = list(client.dataset(run.default_dataset_id).iterate_items())
print(len(items), "rows")
```

More examples: https://github.com/datawharf-tools/examples

### FAQ

**How do I search PubMed, Crossref and ClinicalTrials.gov at once?** Use `mode: "all"` with a `query`. Every source returns the same columns with the DOI, PMID or NCT number.

**How do I list recruiting phase 3 trials for a condition?** Use `mode: "clinicalTrials"`, `condition`, `trialStatus: ["RECRUITING"]` and `trialPhase: ["PHASE3"]`.

**Does it return abstracts?** No, on purpose: it returns citation metadata and links only.

### Pricing

Pay per event: **$0.40 per 1,000 result rows** (`result-item`, $0.0004 each) plus Apify's standard start event. The closest incumbent charges per tool call (about $0.0625 per call), so a call that returns 50 rows here costs about $0.02.

### Data sources

Crossref REST API (https://api.crossref.org), NCBI E-utilities (https://eutils.ncbi.nlm.nih.gov), ClinicalTrials.gov API v2 (https://clinicaltrials.gov/api/v2).

### Related Actors

- [SEC EDGAR Filings & XBRL Data](https://apify.com/datawharf-tools/sec-edgar-api) for biotech and pharma company filings next to the trials you find here.

# Actor input Schema

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

all = Crossref papers + PubMed + ClinicalTrials.gov (max results applies to each source). Or pick one source.

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

Topic, drug, gene or keywords, e.g. 'CRISPR gene therapy'. For PubMed you can use PubMed syntax.

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

YYYY-MM-DD. Publication date for papers and PubMed; study start date for trials.

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

YYYY-MM-DD. Same meaning as 'Date from'.

## `maxResultsPerSource` (type: `integer`):

Maximum rows from each source. You are charged per row returned. In 'all' mode the total can be three times this number.

## `maxAuthors` (type: `integer`):

How many authors to list per paper (the total is in authorCount).

## `journal` (type: `string`):

Restrict to a journal name, e.g. 'Nature Medicine'. PubMed matches exactly; Crossref matches loosely (Nature also returns Nature India).

## `crossrefType` (type: `string`):

Crossref only, e.g. journal-article, proceedings-article, book-chapter, posted-content, dissertation.

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

Disease or condition for ClinicalTrials.gov, e.g. 'type 2 diabetes'. Can be used without a query in Clinical trials mode.

## `trialStatus` (type: `array`):

Any of NOT_YET_RECRUITING, RECRUITING, ENROLLING_BY_INVITATION, ACTIVE_NOT_RECRUITING, COMPLETED, SUSPENDED, TERMINATED, WITHDRAWN, UNKNOWN. Empty = all.

## `trialPhase` (type: `array`):

Any of EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4, NA. Empty = all.

## `maxApiCalls` (type: `integer`):

Safety limit on requests to the three public APIs in this run. The run ends cleanly when reached.

## Actor input object example

```json
{
  "mode": "all",
  "query": "CRISPR gene therapy",
  "maxResultsPerSource": 5,
  "maxAuthors": 5,
  "maxApiCalls": 100
}
```

# Actor output Schema

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

All papers, PubMed citations and trials in the default dataset (table, CSV, JSON, Excel).

## `report` (type: `string`):

Summary of the run written to the default key-value store.

# 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 = {
    "query": "CRISPR gene therapy",
    "maxResultsPerSource": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("datawharf-tools/research-search").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 = {
    "query": "CRISPR gene therapy",
    "maxResultsPerSource": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("datawharf-tools/research-search").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 '{
  "query": "CRISPR gene therapy",
  "maxResultsPerSource": 5
}' |
apify call datawharf-tools/research-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datawharf-tools/research-search"
        }
    }
}
```

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/Swph8s3EtoBUcriYI/builds/CHvKbi5jJfG5H5JX2/openapi.json
