# PubMed & Europe PMC to Markdown (abstracts + OA full text) (`vellumlabs/pubmed-to-markdown`) Actor

Search PubMed and Europe PMC, or pass PMIDs, PMCIDs and DOIs, and get LLM-ready Markdown with YAML front matter: abstract, authors, MeSH, keywords, citations, license. Open-access papers include full text with sections, tables and references. Official API only. Pay per article.

- **URL**: https://apify.com/vellumlabs/pubmed-to-markdown.md
- **Developed by:** [Vellum Kasane](https://apify.com/vellumlabs) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 article 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?

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

Turn **PubMed and Europe PMC search results into LLM-ready Markdown**. Give it a search query or a list of PMIDs, PMCIDs or DOIs. Each article comes back as **one Markdown file with YAML front matter**: title, authors, journal, date, abstract, MeSH terms, keywords, citation count and license. For **open-access papers** you also get the **full text**: sections, tables as GitHub-flavoured Markdown, formulas, figure captions and the numbered reference list.

- **Price: $0.002 per article record** (metadata + abstract), **$0.004 per open-access full-text article**, plus $0.005 per run. 1,000 abstracts cost about $2.
- **Official API only.** All data comes from the [Europe PMC REST API](https://europepmc.org/RestfulWebService), which covers all of PubMed/MEDLINE plus PubMed Central, preprints and more. No HTML scraping, no proxies, no blocking.
- **Built for RAG, AI agents and literature reviews.** Drop the files into a vector store, an Obsidian vault or a Claude Code / LLM wiki, or read the dataset from the [Apify MCP server](https://mcp.apify.com).

#### Output example (one article, shortened)

```markdown
---
title: 'Evaluating large language model clinical reasoning in glaucoma using retrieval-augmented generation'
authors: ['Yin H', 'Miao Q', 'Zhou W', 'Hu C', 'Guo Y', 'Shen L', 'Cai H', 'Grzybowski A', 'Jin K']
journal: 'Advances in ophthalmology practice and research'
date: 2026-05-26
pmid: '42666552'
pmcid: 'PMC13522369'
doi: '10.1016/j.aopr.2026.05.003'
keywords: ['glaucoma', 'Clinical Decision Support', 'Large Language Models', 'Retrieval-augmented Generation']
license: 'cc by-nc-nd'
open_access: true
full_text: true
---

## Evaluating large language model clinical reasoning in glaucoma using retrieval-augmented generation

### Abstract

**Background.** Large language models (LLMs) demonstrate strong performance in knowledge-based medical tasks, yet ...

### 1 Introduction

...

**Table 1.** ...

| ... | ... |
| --- | --- |

### References

1. ...
```

### What does PubMed & Europe PMC to Markdown do?

It searches the biomedical literature the same way you would on PubMed or europepmc.org, then exports each hit as clean, structured Markdown plus JSON fields. It is useful when you need **the text of the papers themselves, not only a list of titles**:

- **Abstracts for every PubMed record**, with structured-abstract labels kept (Background, Methods, Results, Conclusions).
- **Full text for open-access articles** (several million papers in PubMed Central), converted from the publisher's JATS XML: section headings with numbering, paragraphs, bullet lists, **tables as Markdown tables**, display formulas as `$$ ... $$` blocks, figure and table captions, acknowledgments and the reference list.
- **Metadata for filtering and citation**: PMID, PMCID, DOI, authors, ORCID iDs, affiliation, journal and ISO abbreviation, volume, issue, pages, publication types, MeSH terms (and major topics), chemicals, grants, license, Europe PMC citation count, and links to PubMed, PMC, Europe PMC and doi.org.
- **Scheduled monitoring**: with a state key, a weekly run returns only papers it has not exported before, so you can keep a topic feed or a living review up to date.

### Why use it?

- **RAG over medical literature**: every item has a single `markdown_file` field ready to chunk and embed, with front matter you can use as metadata filters (year, MeSH, license, open access).
- **AI agents and MCP clients**: an agent can call the Actor with a query and read back full papers as text, instead of fighting PDF parsing.
- **Systematic and scoping reviews**: export all hits of a search strategy with abstracts and MeSH for screening, then pull full texts of the included studies by PMID.
- **Knowledge bases**: build an Obsidian or Notion library of papers on a topic, one Markdown file per paper.
- **Pharma, biotech and health-tech research**: track new publications on a target, drug or device every week.

### How to use it

1. Click **Try for free** and open the **Input** tab.
2. Type a **search query**, for example `"large language model" AND clinical`, or paste **PMIDs, PMCIDs or DOIs** into the identifier list.
3. Set **Max articles** (this caps your cost) and, if you want only papers with full text, tick **Open-access articles only**.
4. Click **Start**. A run of 10 articles usually finishes in under 10 seconds.
5. Open the **Output** tab: the *Articles* view is a table, the *Markdown files* view shows the files. Download as JSON, CSV, Excel or HTML, or fetch the dataset through the Apify API.

### Input

| Field                 | Type     | Default     | Notes                                                                                                                                                                                    |
| --------------------- | -------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`               | string   |             | [Europe PMC search syntax](https://europepmc.org/searchsyntax): keywords, `"phrases"`, `AND` / `OR` / `NOT`, fields such as `TITLE:`, `AUTH:`, `JOURNAL:`, `MESH:`, `PUB_TYPE:"review"`. |
| `ids`                 | string\[] | `[]`        | PMIDs, PMCIDs, DOIs, or PubMed / PMC / Europe PMC / doi.org URLs. Can be combined with a query.                                                                                          |
| `maxResults`          | integer  | 100         | Maximum articles stored. Each stored article is one billing event.                                                                                                                       |
| `fullText`            | boolean  | `true`      | Convert open-access full text.                                                                                                                                                           |
| `openAccessOnly`      | boolean  | `false`     | Only return open-access articles.                                                                                                                                                        |
| `fromDate` / `toDate` | string   |             | `YYYY` or `YYYY-MM-DD` (first publication date).                                                                                                                                         |
| `sort`                | string   | `relevance` | `relevance` or `newest`.                                                                                                                                                                 |
| `includeReferences`   | boolean  | `true`      | Append the reference list to the full text and return it in `references`.                                                                                                                |
| `stateKey`            | string   |             | Named store that remembers exported articles, for scheduled runs.                                                                                                                        |
| `maxConcurrency`      | integer  | 3           | Parallel requests to Europe PMC (max 8).                                                                                                                                                 |

Example inputs:

```json
{ "query": "\"retrieval augmented generation\" AND clinical", "maxResults": 50, "openAccessOnly": true }
```

```json
{
    "query": "MESH:\"Diabetes Mellitus, Type 2\" AND PUB_TYPE:\"review\"",
    "fromDate": "2025",
    "sort": "newest",
    "maxResults": 200,
    "fullText": false
}
```

```json
{ "ids": ["31452104", "PMC13340859", "10.2196/86073"] }
```

### Output

One dataset item per article. Main fields:

| Field                                                                              | Description                                                          |
| ---------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `title`, `authors`, `journal`, `pub_date`, `pub_year`                              | Bibliographic data                                                   |
| `pmid`, `pmcid`, `doi`, `source`                                                   | Identifiers (`source` is `MED` for PubMed, `PPR` for preprints, ...) |
| `abstract_markdown`                                                                | Abstract as Markdown                                                 |
| `mesh_terms`, `mesh_major_topics`, `keywords`, `chemicals`, `grants`, `pub_types`  | Indexing                                                             |
| `is_open_access`, `license`, `cited_by_count`                                      | Access and impact                                                    |
| `full_text`, `full_text_markdown`, `section_titles`, `table_count`, `figure_count` | Converted full text (open access only)                               |
| `references`, `reference_count`                                                    | Reference list (`label`, `text`, `doi`, `pmid`)                      |
| `markdown_file`                                                                    | Front matter + title + abstract + full text, ready to save as `.md`  |
| `word_count`, `content_hash`, `extraction_error`, `fetched_at`                     | Housekeeping                                                         |

A run summary (matches, stored, full texts, API requests, charged events) is saved as `SUMMARY.json` in the run's key-value store.

### How much does it cost to export PubMed articles?

Pay per event, no subscription:

| Event                                | Price  |
| ------------------------------------ | ------ |
| Run start                            | $0.005 |
| Article record (metadata + abstract) | $0.002 |
| Open-access full-text article        | $0.004 |

Examples: 100 abstracts = $0.205. 500 open-access full texts = $2.005. Each article is charged once, never both events. Open-access bodies shorter than 500 words (conference abstracts, abstract-only deposits) are still returned but charged as a record. Platform usage is small because the Actor only calls a JSON/XML API. Set **Max articles** or a maximum cost per run to cap spending; the Actor stops cleanly when the budget is reached.

### Tips

- **Want only papers you can read in full?** Tick *Open-access articles only*, or add `OPEN_ACCESS:y` to the query.
- **Screening first, full text later**: run with `fullText: false` for cheap abstracts, then pass the included PMIDs with `fullText: true`.
- **Precise searches**: Europe PMC supports field search, e.g. `TITLE:"sepsis" AND AUTH:"Seymour CW"`, `JOURNAL:"Lancet"`, `FIRST_PDATE:[2025-01-01 TO 2025-06-30]`.
- **Weekly feed**: schedule the Actor with `sort: newest`, a `fromDate`, and a `stateKey`.

### FAQ and limitations

- **Is it legal?** The Actor uses the public Europe PMC REST API, the same service EMBL-EBI provides for text mining. Abstracts and metadata are made available for reuse by NLM and Europe PMC; full text is only fetched for articles in the open-access subset, and each item carries its `license` so you can respect reuse terms (for example CC BY-NC).
- **Why no full text for some articles?** Only open-access articles deposited in PubMed Central have full text in the API. Others return metadata and abstract, with the reason in `extraction_error`.
- **Figures** are exported as captions plus the figure file name, not as images.
- **Formulas** use the article's TeX when available; otherwise MathML is converted to readable TeX-like text, which can differ slightly from the typeset version.
- Questions, bugs or a field you need? Open an issue on the **Issues** tab and we will reply.

# Actor input Schema

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

Europe PMC search syntax, same as on europepmc.org: keywords, phrases in quotes, `AND` / `OR` / `NOT`, fields such as `TITLE:`, `AUTH:`, `JOURNAL:`, `MESH:`, `PUB_TYPE:"review"`. Syntax guide: https://europepmc.org/searchsyntax

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

Specific articles to export, e.g. `31452104`, `PMC13340859`, `10.2196/86073`, `https://pubmed.ncbi.nlm.nih.gov/31452104/`. Can be combined with a query.

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

Maximum number of articles to store. Each stored article is one billing event, so this caps your cost.

## `fullText` (type: `boolean`):

For open-access articles in PubMed Central, download the JATS full text and convert it to Markdown (sections, tables, formulas, references). Billed as `article-full-text`; other articles are billed as `article-record`.

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

Restrict results to open-access articles (those with full text).

## `fromDate` (type: `string`):

First publication date, `YYYY` or `YYYY-MM-DD`. Leave empty for no lower bound.

## `toDate` (type: `string`):

`YYYY` or `YYYY-MM-DD`. Leave empty for no upper bound.

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

Relevance (Europe PMC default) or newest first.

## `includeReferences` (type: `boolean`):

Append the numbered reference list to the full-text Markdown and return it in `references`.

## `stateKey` (type: `string`):

Name of a key-value store that remembers exported articles, e.g. `llm-clinical-weekly`. With a state key, scheduled runs return only articles not exported before.

## `maxConcurrency` (type: `integer`):

Parallel API requests to Europe PMC. Keep it low to be polite.

## Actor input object example

```json
{
  "query": "\"large language model\" AND clinical",
  "ids": [],
  "maxResults": 10,
  "fullText": true,
  "openAccessOnly": false,
  "fromDate": "",
  "toDate": "",
  "sort": "relevance",
  "includeReferences": true,
  "stateKey": "",
  "maxConcurrency": 3
}
```

# Actor output Schema

## `articles` (type: `string`):

No description

## `summary` (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 = {
    "query": "\"large language model\" AND clinical",
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("vellumlabs/pubmed-to-markdown").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": "\"large language model\" AND clinical",
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("vellumlabs/pubmed-to-markdown").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": "\\"large language model\\" AND clinical",
  "maxResults": 10
}' |
apify call vellumlabs/pubmed-to-markdown --silent --output-dataset

```

## MCP server setup

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

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/5BGFtOve2borCgaxN/builds/qWTpafWrYjBzLybKy/openapi.json
