# PubMed Papers API (`conserving_celerytop/pubmed-europepmc-papers-api`) Actor

Search PubMed and Europe PMC papers, or look up PMIDs, PMCIDs and DOIs. One row per paper with title, abstract snippet, journal, year, DOI, MeSH terms, keywords, citation count and open access flag. No author fields. Independent tool, not affiliated with Europe PMC or NCBI.

- **URL**: https://apify.com/conserving_celerytop/pubmed-europepmc-papers-api.md
- **Developed by:** [Don Mangu](https://apify.com/conserving_celerytop) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 96.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 paper records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

Use this PubMed API to search research papers or look up PMIDs, PMCIDs and DOIs, and get the title, an abstract snippet, journal, year, DOI, MeSH terms, keywords, citation count and open access flag for $2.00 per 1,000 papers.

Type a search such as "CRISPR AND gene therapy", or paste a list of PubMed IDs and DOIs. Each result is one paper from Europe PMC, which indexes PubMed records, preprints and PubMed Central content. The Actor does not return author, affiliation or e-mail fields. It also removes e-mail addresses that authors write inside an abstract. By default the abstract is a 300 character snippet, because Europe PMC articles stay under publisher copyright. Free text can still name a person, for example a correction notice that names the corresponding author. You need no login, no API key and no proxy.

This is an unofficial tool built by an independent developer. It is not affiliated with, endorsed by or operated by Europe PMC, EMBL-EBI, NCBI or the US National Library of Medicine.

### Sample output

One row per paper. This is a real row from a run on 7 October 2026 with the default Abstract mode, so the abstract is a snippet:

```json
{
  "id": "31516036",
  "source": "MED",
  "pmid": "31516036",
  "pmcid": null,
  "doi": "10.1177/1474515119873648",
  "title": "Mediated effects of insomnia, psychological distress and medication adherence in the association of eHealth literacy and cardiac events among Iranian older patients with heart failure: a longitudinal study.",
  "abstract": "Background Given the importance of improving health for patients with heart failure, the present study examined the temporal associations between eHealth literacy, insomnia, psychological distress, medication adherence, quality of life and cardiac events among older patients with heart failure. Meth...",
  "abstractTruncatedReason": "snippet_mode",
  "journal": "European journal of cardiovascular nursing",
  "journalAbbreviation": "Eur J Cardiovasc Nurs",
  "issn": "1474-5151",
  "volume": "19",
  "issue": "2",
  "pages": "155-164",
  "pubYear": 2020,
  "publicationDate": "2019-09-13",
  "publicationTypes": [
    "Journal Article"
  ],
  "meshTerms": [
    "Humans",
    "Sleep Initiation and Maintenance Disorders",
    "Drug Monitoring",
    "Longitudinal Studies",
    "Telemedicine",
    "Aged",
    "Aged, 80 and over",
    "Middle Aged",
    "Iran",
    "Female",
    "Male",
    "Heart Failure",
    "Medication Adherence",
    "Health Literacy",
    "Surveys and Questionnaires",
    "Psychological Distress"
  ],
  "majorMeshTerms": [
    "Drug Monitoring",
    "Psychological Distress"
  ],
  "keywords": [
    "Quality of life",
    "Cardiac events",
    "Heart Failure",
    "Ehealth Literacy",
    "Mediation Model"
  ],
  "language": "eng",
  "citedByCount": 63,
  "isOpenAccess": false,
  "license": null,
  "hasPdf": false,
  "inPmc": false,
  "openAccessUrl": null,
  "europePmcUrl": "https://europepmc.org/article/MED/31516036",
  "pubmedUrl": "https://pubmed.ncbi.nlm.nih.gov/31516036/",
  "doiUrl": "https://doi.org/10.1177/1474515119873648",
  "query": "31516036",
  "matchedBy": "pmid",
  "retrievedAt": "2026-10-07T12:48:54.968Z",
  "dataSource": "Europe PMC (europepmc.org)",
  "resultStatus": "ok"
}
```

### How to get PubMed papers with this Actor

1. Click **Try for free**. No API key is needed.
2. In **Search queries**, enter one search per line. Use plain words, or Europe PMC syntax such as `MESH:"Asthma" AND child`.
3. Or enter PubMed IDs, PMC IDs or DOIs in **PMIDs, PMCIDs or DOIs**, one per line. You can mix the three types. A PubMed or DOI link also works.
4. Optionally set **Publication year from** and **to**, **Open access only**, **Publication types**, **Source**, **Sort by** and **Abstract mode**. A paper must pass every filter you fill in.
5. Set **Max results**. The default is 100 and the limit is 10,000 rows per run.
6. Click **Start**, open the **Overview** view, and export as JSON, CSV or Excel.

Typical uses:

- Build a reading list or a literature table for a topic, newest or most cited first.
- Turn a column of PMIDs or DOIs in a sheet into titles, journals, years and abstract snippets.
- Check how often a paper is cited, and whether a free full text exists.
- Feed titles, MeSH terms and abstract snippets to a classifier, a search index or a language model.
- Track a topic every week with a schedule and a year filter.

### What you get

| Field | Meaning |
|---|---|
| id, source, pmid, pmcid, doi | Europe PMC record id and source code (MED is a PubMed record, PPR is a preprint), and the identifiers the record has. Any of them can be null |
| title, abstract, abstractTruncatedReason | Plain text. HTML tags are removed. By default abstract is the first 300 characters followed by three dots. abstractTruncatedReason says why a text was cut: snippet_mode, license-not-commercial, no_open_access_cc_licence or abstract_mode_none. abstract is null when the paper has none or Abstract mode is none |
| journal, journalAbbreviation, issn, volume, issue, pages | Where the paper appeared, as published |
| pubYear, publicationDate | Year and first publication date |
| publicationTypes | For example Journal Article, Review, Clinical Trial |
| meshTerms, majorMeshTerms | MeSH descriptor names, and the ones marked as a major topic. Empty for records that are not yet indexed |
| keywords | Keywords listed in the record |
| language | Three-letter language code |
| citedByCount | Number of citing papers that Europe PMC knows at run time |
| isOpenAccess, license, hasPdf, inPmc, openAccessUrl | Open access flag, license of the free full text as Europe PMC gives it (for example cc by), and a link to it when one exists |
| europePmcUrl, pubmedUrl, doiUrl | Links to the record |
| query, matchedBy | The search or identifier that produced the row, and search, pmid, pmcid or doi |
| retrievedAt, dataSource, resultStatus | Read time, Europe PMC, and ok or not_found |

The Actor does not return author fields, affiliations, e-mail fields, ORCID iDs or grant lists. It does not return the full text of a paper.

### Pricing

Pay per event: **$2.00 per 1,000 paper rows** on the Free plan, with lower prices on Bronze ($1.80), Silver ($1.60) and Gold ($1.40) plans. The start of a run costs $0.00005. An identifier that matches no paper returns one not_found row and counts as one result, because the lookup was done. A search with no hits returns nothing and costs nothing.

Worked example: looking up 5 identifiers returns 5 rows and costs 5 x $0.002 = $0.01, plus the start fee. A search that returns 1,000 papers costs 1,000 x $0.002 = $2.00. Four runs of 1,000 rows took between 7.9 and 12.4 seconds on my computer and made 10 requests each to Europe PMC. Rows that were saved before a stop are charged, and rows that were not saved are not.

### Input examples

Search a topic, open access papers from 2023 to 2025, most cited first:

```json
{
  "queries": ["CRISPR AND gene therapy"],
  "yearFrom": 2023,
  "yearTo": 2025,
  "openAccessOnly": true,
  "sort": "most_cited",
  "abstractMode": "full",
  "maxResults": 50
}
```

That input matched 918 papers on 7 October 2026 and returned the 50 most cited. 33 of the 50 rows carried a cc by license and returned the full abstract. 16 rows carried a non-commercial license (cc by-nc, cc by-nc-nd or cc by-nc-sa) and returned a snippet with abstractTruncatedReason license-not-commercial. One row had no license and returned a snippet with no_open_access_cc_licence. The first six:

| PMID | Year | Cited by | Journal | Title |
|---|---|---|---|---|
| 36970624 | 2023 | 434 | Frontiers in bioengineering and biotechnology | Off-target effects in CRISPR/Cas9 gene editing. |
| 36356599 | 2023 | 245 | Nature | Non-viral precision T cell receptor replacement for personalized cell therapy. |
| 36717220 | 2023 | 241 | Gut | Targeting m6A reader YTHDF1 augments antitumour immunity and boosts anti-PD-1 efficacy in colorectal cancer. |
| 38195537 | 2024 | 177 | Molecular cancer | Comprehensive review of CRISPR-based gene editing: mechanisms, challenges, and applications. |
| 37951948 | 2023 | 156 | Nature communications | Lung SORT LNPs enable precise homology-directed repair mediated CRISPR/Cas genome editing. |
| 37188660 | 2023 | 138 | Nature communications | GalNAc-Lipid nanoparticles enable non-LDLR dependent hepatic delivery of a CRISPR base editing therapy. |

Look up papers by identifier:

```json
{
  "ids": ["31516036", "10.1038/nature12373", "PMC3000000"]
}
```

Review articles about a topic, without abstracts:

```json
{
  "queries": ["type 2 diabetes AND exercise"],
  "publicationTypes": ["Review"],
  "yearFrom": 2020,
  "abstractMode": "none"
}
```

### Output example for an identifier that matches nothing

A real row for the PubMed ID 99999999:

```json
{
  "id": null,
  "source": null,
  "pmid": null,
  "pmcid": null,
  "doi": null,
  "title": null,
  "abstract": null,
  "abstractTruncatedReason": null,
  "journal": null,
  "journalAbbreviation": null,
  "issn": null,
  "volume": null,
  "issue": null,
  "pages": null,
  "pubYear": null,
  "publicationDate": null,
  "publicationTypes": null,
  "meshTerms": null,
  "majorMeshTerms": null,
  "keywords": null,
  "language": null,
  "citedByCount": null,
  "isOpenAccess": null,
  "license": null,
  "hasPdf": null,
  "inPmc": null,
  "openAccessUrl": null,
  "europePmcUrl": null,
  "pubmedUrl": null,
  "doiUrl": null,
  "query": "99999999",
  "matchedBy": null,
  "retrievedAt": "2026-10-07T12:48:54.985Z",
  "dataSource": "Europe PMC (europepmc.org)",
  "resultStatus": "not_found"
}
```

### Run it every week

Europe PMC adds new records every day. In the Apify Console, open **Schedules**, create a schedule with the cron expression `0 6 * * 1`, and add this Actor with your search and a Publication year from. Use a dataset export, a webhook, or an integration with Make, Zapier or n8n to send the rows on. You can also call the Actor from your own code with the Apify API.

### Run it every day

Use a saved Task and a schedule to get only the papers you have not received before.

1. Open the Actor, fill in your search or your identifiers, tick **Only new since the last run** and give the search a **Monitor name**, for example `crispr-daily`. Use one monitor name per saved task.
2. Click **Save as a new task**.
3. In the Apify Console open **Schedules**, click **Create new**, pick your Task and enter a cron expression for once a day, for example `0 7 * * *` (every day at 07:00).
4. Each run returns only papers that the monitor has not delivered before. The first run returns everything that matches, up to **Max results**, and becomes the baseline.

Settings that suit a daily run:

- Set **Sort by** to Newest first, so the newest papers come first.
- Set **Max results** above the number of new papers you expect in a day. Papers that Max results cuts off are not remembered, so the next run delivers them.
- Changing a search value, such as a query, a filter or the source, starts a new memory, and the next run counts as a first run. Changing **Max results**, **Sort by**, **Abstract mode** or the list of identifiers does not.
- A paper is delivered once. Citation counts and other fields that change later do not bring it back.
- An identifier that matches no paper returns one not_found row the first time only. The lookup is repeated in every run, so the paper is delivered as soon as Europe PMC has it.

Where the memory lives: in a key-value store in your own Apify account named `pubmed-monitor-<monitorName>`. It holds record ids only, such as `MED:31516036`, and no paper content. A run with no new papers saves no rows and charges no results, only the start of the run.

Worked example on the Free plan, with the prices above ($0.002 per row, $0.00005 per start). Assume a saved task with Max results set to 100.

- First run, 100 rows: 100 x $0.002 + $0.00005 = $0.20005.
- A day with 8 new papers: 8 x $0.002 + $0.00005 = $0.01605.
- A day with no new papers: $0.00005.
- A 30 day month with 8 new papers every day: 30 x $0.01605 = $0.4815.

Papers that the monitor skips because it delivered them before are never charged.

### Bulk lists

Instead of typing identifiers, you can give the Actor a Dataset or a file. Both are added to the identifiers typed in **PMIDs, PMCIDs or DOIs**, and the typed list can stay empty.

- **Dataset with the list**: pick an Apify Dataset in which each item holds one identifier. In **Field in the dataset**, enter the name of the field that holds it, for example `pmid`. If you leave the field name empty, the Actor takes the first text field it finds.
- **List file URL**: the web address of a `.txt`, `.csv` or `.json` file. A text file has one identifier per line. A CSV file uses the first column. A JSON file is an array. A header row is skipped. The file can be up to 10 MB and must be on a public web address.

The entries are de-duplicated, and the limit of 1,000 identifiers applies to the merged list. An entry that is not a PMID, a PMCID or a DOI ends the run with a message before any request, and nothing is charged. The price is the same per row as for a typed list.

Together with **Only new since the last run**, a file or a Dataset that grows over time delivers only the identifiers you added since the last run.

### FAQ

**Where does the data come from?** From the Europe PMC REST API (europepmc.org), run by EMBL-EBI. Europe PMC indexes PubMed records, plus preprints and PubMed Central content. The Actor reads the public search endpoint and does not use a key.

**Is it legal to use?** The rules differ by source, and this is not legal advice. The Europe PMC Copyright page (https://europepmc.org/Copyright) says that automated retrieval is allowed only through its OAI, RESTful, SOAP and bulk services. This Actor uses the RESTful service. The same page says that the articles stay under the copyright of the publishers and authors, and that reuse beyond fair use needs permission from the copyright owner. EMBL-EBI also states in its terms of use that it adds no restriction beyond those of the data owner, and it expects attribution. NCBI states that NLM does not claim copyright on PubMed abstracts, but that journal publishers or authors may. For these reasons the Actor is careful with abstracts. The default Abstract mode is `snippet`: the first 300 characters followed by three dots. Mode `none` returns no abstract. Mode `full` returns the whole abstract only for open access papers whose license field shows cc0, cc by or cc by-sa, because these licenses allow commercial use. A paper with a non-commercial or no-derivatives license (NC or ND) returns a snippet and the reason license-not-commercial. A paper without an open access Creative Commons license returns a snippet and the reason no_open_access_cc_licence. Read the license field before you republish a text, because attribution still applies. Titles, identifiers, journal data, MeSH terms, keywords and counts are not abstracts. Check the rules of the publisher before you reuse text. Data: Europe PMC (europepmc.org).

**Why are there no authors?** Author names, affiliations and e-mail addresses are personal data. The Actor does not read the author, affiliation and author ID fields into the output, so the rows are lower risk under privacy rules. The title and abstract are free text and can still contain a name, for example a correction notice that says who the corresponding author is. The Actor also removes e-mail addresses that are written inside abstract or title text before it cuts the text. In a test on 6 papers with addresses in their text on 7 October 2026, it removed 11 addresses and none were left. In a general run of 3,000 rows it removed none, because most abstracts have no address. Chemistry names such as MoS2@M.bvs are kept.

**What does a search match?** By default, your words must appear in the title or abstract. Without that limit, Europe PMC also matches text outside the title and abstract, and that returned many off-topic rows in a test: with the most cited first, only 3 of 50 rows mentioned CRISPR in the title, abstract, MeSH terms or keywords. Choose Everywhere in **Search in** only when you want full text hits. A query that names a field, such as `MESH:"Asthma"`, is used as you typed it.

**How complete is the data?** It depends on the paper. In a run of 1,000 rows on 7 October 2026 (search "cancer AND immunotherapy", from 2018), 87.7% of rows had an abstract (a snippet by default), 99.6% a DOI, 75.1% keywords, 50.7% MeSH terms and 55.9% were open access. Recent papers often have no MeSH terms yet.

**What does the Review filter return?** Europe PMC matches the word. In a run of 200 rows with Publication types set to Review, 147 rows listed Review, and the other 53 listed a related type such as Systematic Review or Scoping Review.

**Why is a publication year in the future?** Some records are published online ahead of the issue, and Europe PMC then shows the issue year. A real row from 7 October 2026 shows 2027.

**How do identifiers match?** A PMID matches PubMed records only. A PMCID and a DOI match any Europe PMC record. If two identifiers point to the same paper, it is returned once. An identifier link from pubmed.ncbi.nlm.nih.gov, doi.org or pmc.ncbi.nlm.nih.gov also works.

**What are the limits?** Up to 50 searches, 1,000 identifiers and 10,000 rows per run. Max results counts all rows, including not_found rows. The Actor makes at most 3 requests per second.

**What if the run fails?** If Europe PMC is down or sends a reply the Actor cannot read, the run stops with a clear message. Rows saved before the stop stay in the dataset. Run it again later.

### Related Actors

Other public-data Actors by the same author are listed on the author's Store profile.

I built this Actor myself as an independent developer. Data: Europe PMC (europepmc.org).

# Actor input Schema

## `queries` (type: `array`):

Enter one search per line, in plain words or in PubMed and Europe PMC syntax, for example: CRISPR AND gene therapy, or MESH:"Diabetes Mellitus" AND exercise. Leave empty if you only look up identifiers.

## `searchIn` (type: `string`):

Where plain search words must appear. Title and abstract gives on-topic results. A query that names a field, such as MESH:"Asthma", is used as typed.

## `ids` (type: `array`):

Enter one identifier per line: a PubMed ID such as 31516036, a PMC ID such as PMC3000000, or a DOI such as 10.1038/nature12373. An identifier that matches nothing returns one not_found row. Filters do not apply to lookups.

## `listDatasetId` (type: `string`):

Pick an Apify Dataset that holds your list, one entry per item. It is added to the entries typed above.

## `listDatasetField` (type: `string`):

Name of the dataset field that holds the entry. Leave empty to use the first text field it finds.

## `listFileUrl` (type: `string`):

Web address of a .txt, .csv or .json file with one entry per line. A header row is skipped. Up to 10 MB.

## `yearFrom` (type: `integer`):

Keep papers published in this year or later, for example 2020.

## `yearTo` (type: `integer`):

Keep papers published in this year or earlier, for example 2025.

## `openAccessOnly` (type: `boolean`):

Keep only papers with a free full text in Europe PMC.

## `publicationTypes` (type: `array`):

Keep only these publication types. Leave empty for all types.

## `source` (type: `string`):

Which part of Europe PMC to search. PubMed records is the default.

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

Order of the search results.

## `onlyNew` (type: `boolean`):

Return only items that this monitor has not delivered before. The first run returns everything and becomes the baseline. Use it with a daily schedule.

## `monitorName` (type: `string`):

Names the memory of this monitor. Use one name per saved task, so two tasks never share their memory.

## `abstractMode` (type: `string`):

Europe PMC says articles stay under publisher copyright. Snippet returns the first 300 characters and is the default. Full returns the whole abstract only for open access papers with a license that allows commercial use (cc0, cc by, cc by-sa). Papers with a non-commercial or no-derivatives license, or no license, return a snippet. The field abstractTruncatedReason tells you why a text was cut.

## `maxResults` (type: `integer`):

Return at most this many rows in total, across all searches and lookups, including not_found rows. Each row returned is one charged result.

## Actor input object example

```json
{
  "queries": [
    "CRISPR AND gene therapy"
  ],
  "searchIn": "title_abstract",
  "openAccessOnly": false,
  "source": "pubmed",
  "sort": "relevance",
  "onlyNew": false,
  "monitorName": "default",
  "abstractMode": "snippet",
  "maxResults": 25
}
```

# Actor output Schema

## `papers` (type: `string`):

No description

## `stats` (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 = {
    "queries": [
        "CRISPR AND gene therapy"
    ],
    "maxResults": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("conserving_celerytop/pubmed-europepmc-papers-api").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 = {
    "queries": ["CRISPR AND gene therapy"],
    "maxResults": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("conserving_celerytop/pubmed-europepmc-papers-api").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 '{
  "queries": [
    "CRISPR AND gene therapy"
  ],
  "maxResults": 25
}' |
apify call conserving_celerytop/pubmed-europepmc-papers-api --silent --output-dataset

```

## MCP server setup

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

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/W8AF7IFUjdXxuHx6D/builds/mBwSuEzVFpdhdxIox/openapi.json
