# PubMed articles search - abstracts, authors, MeSH (E-utilities) (`retrainmapdata/pubmed-articles`) Actor

Search PubMed via NCBI's public E-utilities (esearch + efetch): one row per article with PMID, title, abstract, authors, journal, publication date, DOI, PMC id, MeSH terms, keywords and publication types. PubMed query syntax, date range, optional NCBI API key. Default: GLP-1 weight loss, last year.

- **URL**: https://apify.com/retrainmapdata/pubmed-articles.md
- **Developed by:** [RetrainMap Data](https://apify.com/retrainmapdata) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 records

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

## PubMed articles search — abstracts, authors, MeSH (E-utilities)

One row per PubMed article from NCBI's public E-utilities (esearch + efetch, `db=pubmed`).
Search with PubMed's own query syntax and a publication-date range; get PMID, title,
abstract, authors, journal, volume/issue/pages, publication date, DOI, PMC id, MeSH terms,
keywords, publication types, language and links — normalised, one flat row per article,
ready for CSV or JSON.

**The default input ("GLP-1 weight loss", last 365 days, 100 rows) succeeds within
5 minutes and returns rows** — Apify auto-tests it daily.

### Data source and status

| | |
|---|---|
| Publisher | National Library of Medicine (NLM), National Center for Biotechnology Information (NCBI) |
| API | https://eutils.ncbi.nlm.nih.gov/entrez/eutils/ — public; no key needed (an optional free NCBI API key raises the rate limit). Documentation: https://www.ncbi.nlm.nih.gov/books/NBK25499/ |
| What this Actor reads | `esearch.fcgi` (`db=pubmed`, `term`, `retmax`, `sort`, `datetype=pdat`, `mindate`/`maxdate`, JSON) for the PMIDs, then `efetch.fcgi` (`retmode=xml`, 100 PMIDs per request) for the records; every request carries `tool=retrainmap` and `email=<contact>` as NCBI's usage policy asks |
| Refresh cadence | PubMed is updated **daily, Tuesday–Saturday** (new citations appear each morning US Eastern). The Actor reads live on every run; `fetched_at` on each row is the fetch time |
| Terms / attribution | PubMed data are provided by NLM (https://www.nlm.nih.gov/web\_policies.html); the E-utilities usage policy (https://www.ncbi.nlm.nih.gov/books/NBK25497/) asks for ≤ 3 requests/second without a key (10 with one), identification via `tool`/`email`, and that large jobs run on weekends or 9 pm–5 am US Eastern on weekdays. Abstracts remain copyrighted by their publishers; please cite PubMed/NLM as the source |
| Known caveats | `esearch` returns at most 10,000 ids per query — narrow the date range for more; `abstract` is empty when PubMed holds none (many older or non-English records) and is cut at 5,000 characters (`abstract_truncated` says so); `mesh_terms` and `publication_types` are empty until NLM indexes the citation (weeks to months after publication); `pub_date` follows the journal's PubDate and may be a year only or a range string like `2025 Jan-Feb`; NCBI Bookshelf entries in the results are skipped and counted in the run summary |

Honesty note: the rows are the PubMed XML's own elements flattened — nothing is inferred,
summarised or classified by this Actor, and a run stops with an error rather than guess
when the API's shape changes.

Identification: every request carries NCBI's `tool` and `email` parameters, a product-token
User-Agent and the operator's contact address in the standard `From:` header (RFC 9110
§10.1.2). An API key you supply is sent only to eutils.ncbi.nlm.nih.gov and never logged.

### Input

| Field | Type | Meaning |
|---|---|---|
| `query` | string | PubMed search syntax: plain words, `semaglutide[Title]`, `diabetes[MeSH Terms]`, `randomized controlled trial[Publication Type]`, `Smith J[Author]`, `AND`/`OR`/`NOT` |
| `date_from` / `date_to` | `YYYY-MM-DD` | Publication date, inclusive. Both empty = the last 365 days; `1900-01-01` for no lower bound |
| `sort` | `pub_date` / `relevance` / `most_recent` | Default `pub_date` (newest first) |
| `include_abstracts` | boolean | Default true |
| `max_records` | integer | Default 200 (prefilled 100), at most 10,000 |
| `ncbi_api_key` | secret string | Optional; 10 requests/second instead of 3 |
| `contact_email` | string | NCBI `email` parameter and `From:` header |

Example — semaglutide randomised controlled trials published in 2025, without abstracts:

```json
{ "query": "semaglutide[Title] AND randomized controlled trial[Publication Type]", "date_from": "2025-01-01", "date_to": "2025-12-31", "include_abstracts": false, "max_records": 25 }
```

### Output (dataset row)

`pmid`, `title`, `abstract` (labelled sections joined as `LABEL: text`, ≤ 5,000 chars),
`abstract_truncated`, `authors` (`ForeName LastName` or collective name), `journal`,
`journal_abbrev`, `volume`, `issue`, `pages`, `pub_date`, `pub_year`, `epub_date`, `doi`,
`pmc_id`, `mesh_terms`, `mesh_major`, `keywords`, `publication_types`, `language`,
`pubmed_url`, `pmc_url`, `doi_url`, `fetched_at`, `source`.

A run summary (filters, PubMed's own query translation and match count, efetch batches,
skipped Bookshelf entries, esearch warnings, requests, whether the pay-per-event budget
stopped the run) is stored as `RUN_SUMMARY` in the run's key-value store.

### Pricing (pay per event)

| Event | Price |
|---|---|
| `run-start` — once per run | $0.10 |
| `record` — per row written | $0.005 |

The default 100-article pull costs $0.60; 1,000 articles cost $5.10. Rows stop when your
run's maximum charge is reached; the run summary says so.

### Operator

Steelyard Ventures LLC (RetrainMap) — info@steelyardclinical.com. Not affiliated with NLM,
NCBI or the NIH. The Actor writes only to its own dataset and key-value store; it stores
no credentials and sends nothing else.

# Actor input Schema

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

Any PubMed search, exactly as on pubmed.ncbi.nlm.nih.gov: plain words, field tags such as semaglutide\[Title], diabetes\[MeSH Terms], randomized controlled trial\[Publication Type], Smith J\[Author], and AND / OR / NOT. PubMed's own query translation is stored in the run summary.

## `date_from` (type: `string`):

Optional; filters on the publication date (datetype=pdat). When both dates are empty the Actor uses the last 365 days. Use 1900-01-01 for no lower bound.

## `date_to` (type: `string`):

Optional, inclusive.

## `sort` (type: `string`):

esearch sort: publication date (newest first), relevance (PubMed best match), or most recently added to PubMed.

## `include_abstracts` (type: `boolean`):

When off, the abstract column is left empty (the rest of the row is unchanged).

## `max_records` (type: `integer`):

Stop after this many articles have been written. esearch returns at most 10,000 ids per query; narrow the date range for more. Articles are fetched 100 per efetch request.

## `ncbi_api_key` (type: `string`):

Raises NCBI's limit from 3 to 10 requests per second (free, from https://account.ncbi.nlm.nih.gov/settings/). Sent only to eutils.ncbi.nlm.nih.gov as the api\_key parameter; never logged or stored.

## `contact_email` (type: `string`):

NCBI asks every E-utilities client to identify itself with tool and email parameters (tool=retrainmap); the address is also sent in the standard From: request header (RFC 9110 s10.1.2).

## Actor input object example

```json
{
  "query": "GLP-1 weight loss",
  "sort": "pub_date",
  "include_abstracts": true,
  "max_records": 100,
  "contact_email": "info@steelyardclinical.com"
}
```

# Actor output Schema

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

Every matched article as one row: PMID, title, abstract, authors, journal, publication date, DOI, PMC id, MeSH terms, keywords, publication types, PubMed link.

## `results_csv` (type: `string`):

The same rows as a CSV file.

# 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": "GLP-1 weight loss",
    "max_records": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("retrainmapdata/pubmed-articles").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": "GLP-1 weight loss",
    "max_records": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("retrainmapdata/pubmed-articles").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": "GLP-1 weight loss",
  "max_records": 100
}' |
apify call retrainmapdata/pubmed-articles --silent --output-dataset

```

## MCP server setup

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

```

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/k7t5YLlNUQyYC6Tj7/builds/LShUtnt0CkEuSwfcm/openapi.json
