# PubMed Search Scraper (`crawlerbros/pubmed-search-scraper`) Actor

Search PubMed (NCBI E-utilities) for biomedical articles by keyword, date range, and article type. Returns title, authors, journal, abstract, DOI, MeSH terms, keywords, and citation. Free public API, no proxy, no cookies. Optional NCBI API key for higher rate limits.

- **URL**: https://apify.com/crawlerbros/pubmed-search-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Developer tools, Other, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 9 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 results

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

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Search Scraper

Search [PubMed](https://pubmed.ncbi.nlm.nih.gov) — the world's largest biomedical literature database, covering 35M+ articles from 1966 onwards — by keyword, date range, and article type. Returns structured records with title, authors, journal, abstract, DOI, MeSH terms, keywords, and a clean citation. HTTP-only via NCBI's free public **E-utilities** API. No proxy, no cookies.

### What it does

You provide one or more search terms (or paste full PubMed search URLs); the actor:

1. Builds a PubMed query for each term, optionally narrowed by date range, article type, and free-full-text flag.
2. Calls **`esearch`** to get the matching PMIDs (paginated).
3. Calls **`esummary`** in batches of 200 for the metadata (title, authors, journal, dates, DOI, publication types).
4. Calls **`efetch`** in batches of 50 for the abstract, MeSH headings, and author keywords.
5. Merges everything into one flat record per article, dedupes across search terms by PMID, and pushes to the dataset.

Empty fields are omitted (no nulls) — when an article has no abstract or no MeSH terms, those keys are simply absent.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `searchTerms` | array of strings (required) | `["machine learning oncology"]` | One or more PubMed queries. Supports full PubMed syntax — boolean (`AND`/`OR`/`NOT`), MeSH (`cancer[MeSH]`), field tags, etc. |
| `searchUrls` | array of strings | `[]` | Optional. Paste full PubMed search URLs; the actor extracts the `term=` param and merges with `searchTerms`. |
| `pmidList` | array of strings | `[]` | Optional **direct-lookup mode** — list of PubMed IDs to fetch without searching (e.g. `["38123456", "36438426"]`). Bypasses `esearch` and goes straight to `esummary`/`efetch`. Combine with or use instead of `searchTerms`. |
| `maxItemsPerTerm` | integer | `25` (1–500) | Per-term result cap. Total dataset = sum across terms minus duplicates. |
| `dateFrom` | string | – | Earliest publication date, `YYYY/MM/DD` (e.g. `2024/01/01`). Optional. |
| `dateTo` | string | – | Latest publication date, `YYYY/MM/DD`. Optional. |
| `articleType` | enum | `any` | One of `any`, `review`, `clinical_trial`, `meta_analysis`, `case_report`, `randomized_controlled_trial`, `systematic_review`, `editorial`, `letter`, `comment`, `practice_guideline`, `observational_study`, `comparative_study`, `multicenter_study`. |
| `freeFullTextOnly` | boolean | `false` | If true, restrict to articles with free full-text access (PMC). |
| `language` | enum | `any` | Restrict by article language. One of `any`, `english`, `spanish`, `french`, `german`, `chinese`, `japanese`, `italian`, `portuguese`, `russian`, `korean`. |
| `journalFilter` | string | – | Restrict to a specific journal (exact name, e.g. `Nature` or `New England Journal of Medicine`). Optional. |
| `authorFilter` | string | – | Restrict to articles by a specific author in PubMed format (e.g. `Smith J` or `Smith JR`). Optional. |
| `meshFilter` | array of strings | `[]` | Restrict to articles tagged with these MeSH (Medical Subject Headings) terms — AND-joined (e.g. `["Lung Neoplasms", "Machine Learning"]` returns articles tagged with both). |
| `affiliationFilter` | string | – | Restrict to articles where any author's affiliation contains this substring (e.g. `Harvard`, `Mayo Clinic`, `Beijing`). Optional. |
| `includeCitedByCount` | boolean | `false` | Add a `citedByCount` field to each record via NCBI elink. Adds 1 elink call per page of PMIDs. Useful for citation-network analysis. |
| `apiKey` | string (Secret, optional) | – | Free NCBI API key. Raises rate limit from 3 → 10 req/s. Sign up at https://www.ncbi.nlm.nih.gov/account/. Useful for bulk runs. |

#### Example input

```json
{
  "searchTerms": ["machine learning oncology", "covid vaccine efficacy"],
  "maxItemsPerTerm": 50,
  "dateFrom": "2023/01/01",
  "dateTo": "2024/12/31",
  "articleType": "review",
  "freeFullTextOnly": true
}
````

### Output

One record per unique article. Empty fields are omitted (no nulls).

```json
{
  "pmid": "38123456",
  "title": "Machine learning for early lung-cancer detection: a systematic review",
  "authors": ["Smith J", "Doe JR", "Brown KL"],
  "authorsAbbreviated": ["Smith J", "Doe JR", "Brown KL"],
  "authorCount": 3,
  "journal": "Nature Reviews Oncology",
  "journalAbbrev": "Nat Rev Oncol",
  "publicationDate": "2024-03-15",
  "epubDate": "2024-02-20",
  "volume": "21",
  "issue": "5",
  "pages": "300-315",
  "issn": "1759-4774",
  "elocationId": "doi: 10.1000/foo",
  "language": "eng",
  "doi": "10.1000/foo",
  "pmcId": "PMC9876543",
  "pmcUrl": "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9876543/",
  "abstract": "BACKGROUND: Lung cancer remains... METHODS: We searched MEDLINE...",
  "meshTerms": ["Lung Neoplasms", "Machine Learning", "Early Detection of Cancer"],
  "keywords": ["deep learning", "screening", "CT imaging"],
  "authorAffiliations": ["Harvard Medical School, Boston, USA.", "MIT, Cambridge, USA."],
  "conflictOfInterest": "The authors declare no conflict of interest.",
  "grants": [
    {"grantId": "R01-CA-12345", "agency": "NCI NIH HHS", "country": "United States"}
  ],
  "referenceCount": 86,
  "citedByCount": 8,
  "articleTypes": ["Journal Article", "Systematic Review"],
  "tags": ["Systematic Review", "Free article"],
  "articleUrl": "https://pubmed.ncbi.nlm.nih.gov/38123456/",
  "shareLinks": {
    "twitter": "https://twitter.com/intent/tweet?text=...",
    "facebook": "https://www.facebook.com/sharer/sharer.php?u=...",
    "permalink": "https://pubmed.ncbi.nlm.nih.gov/38123456/"
  },
  "citation": "Smith J, Doe JR, Brown KL. Machine learning for early lung-cancer detection: a systematic review. Nat Rev Oncol. 2024;21(5):300-315. doi:10.1000/foo",
  "inputQuery": "machine learning oncology",
  "scrapedAt": "2024-12-16T14:23:11+00:00"
}
```

#### Output fields

- **`pmid`** — PubMed ID (stable, never changes).
- **`title`** — article title (trailing period stripped).
- **`authors`** / **`authorsAbbreviated`** / **`authorCount`** — full and abbreviated author lists + count.
- **`journal`** / **`journalAbbrev`** — full journal name + abbreviated (NLM-style) name.
- **`publicationDate`** — ISO date `YYYY-MM-DD` (best parse from PubMed's free-form `pubdate`).
- **`epubDate`** — ISO date of electronic publication when available.
- **`volume`** / **`issue`** / **`pages`** / **`issn`** / **`elocationId`** — bibliographic identifiers when present.
- **`language`** — ISO 639-2 code (e.g. `eng`, `spa`, `chi`).
- **`doi`** — Digital Object Identifier when registered.
- **`pmcId`** — PubMed Central ID (e.g. `PMC1234567`) when the article is in PMC's open-access archive.
- **`pmcUrl`** — direct URL to the free full-text version on PubMed Central (when `pmcId` is set).
- **`abstract`** — full abstract text. Multi-section abstracts are flattened with section labels (e.g. `"BACKGROUND: ... METHODS: ..."`).
- **`meshTerms`** — array of MeSH descriptor names (curated medical subject headings).
- **`keywords`** — author-supplied keywords (when available).
- **`authorAffiliations`** — deduped list of institutional affiliations parsed from author metadata (e.g. `["Harvard Medical School, Boston, USA.", "MIT, Cambridge, USA."]`).
- **`conflictOfInterest`** — author-declared conflict-of-interest statement (when present).
- **`grants`** — funding sources as `[{grantId, agency, country}]` rows (NIH grants, foundation grants, etc.).
- **`referenceCount`** — number of references cited by this article (parsed from PubMed's reference list).
- **`citedByCount`** — number of PubMed articles citing this article. Only populated when `includeCitedByCount: true`.
- **`articleTypes`** — raw publication types from PubMed.
- **`tags`** — derived human-readable tags from `articleTypes` (`Review`, `Systematic Review`, `Meta-Analysis`, `Clinical Trial`, `Case Report`, `Randomized Controlled Trial`) plus `Free article` when `freeFullTextOnly` is set.
- **`articleUrl`** — direct link to the PubMed page.
- **`shareLinks`** — `{twitter, facebook, permalink}` pre-filled share URLs.
- **`citation`** — compact AMA-style citation string assembled from the metadata.
- **`inputQuery`** — the search term (or extracted-from-URL term) that surfaced this article.
- **`scrapedAt`** — ISO-8601 UTC timestamp.

### Use cases

- **Literature reviews** — build a structured corpus of every relevant paper for a systematic review or meta-analysis.
- **Research-trend tracking** — monitor weekly/monthly volume of publications on a topic to spot rising fields.
- **Bibliometric analysis** — pull thousands of records with structured authors/journals for citation-network analysis.
- **Author / journal mapping** — find every paper by a specific researcher or in a target journal across a date range.
- **Curated newsletters** — generate a fresh weekly list of new articles matching your topic + filter combination.

### FAQ

**Does it need a proxy or cookies?**
No. PubMed's E-utilities is fully public and works from datacenter IPs. No login or auth required.

**Do I need an API key?**
No — the free public limit is 3 requests/second, plenty for default-sized runs. Supply an optional `apiKey` (free signup at https://www.ncbi.nlm.nih.gov/account/) to raise the limit to 10 req/s for bulk extraction.

**Can I search by author, journal, or MeSH term?**
Yes — PubMed query syntax is fully supported. Examples:

- Author: `Smith J[Author]`
- Journal: `"Nature Reviews Oncology"[Journal]`
- MeSH: `Cancer[MeSH] AND machine learning`
- Combine: `(cancer OR tumor) AND machine learning AND 2023:2024[dp]`

**Why is my abstract empty?**
\~5% of PubMed records ship without an abstract — usually editorials, letters, or older articles. The `abstract` field is simply omitted in those cases (omit-empty contract).

**How does deduplication work?**
Across search terms within the same run, articles are deduped by PMID. Each article appears at most once in the dataset, with `inputQuery` set to the first term that surfaced it.

**What if my query has zero results?**
You get a single sentinel record `{type: "pubmed_scraper_error", reason: "no_results", searchTerms: [...]}` so the dataset is non-empty. The run completes successfully — empty datasets aren't treated as failures.

**Can I paste PubMed URLs instead of writing terms?**
Yes — drop full URLs like `https://pubmed.ncbi.nlm.nih.gov/?term=cancer+immunotherapy` into `searchUrls`. The actor extracts the `term=` param and treats it as a search term.

**Is the data fresh?**
PubMed updates within hours of publication for indexed journals. The actor pulls live every run; results reflect PubMed's current state at fetch time.

# Actor input Schema

## `searchTerms` (type: `array`):

One or more PubMed search queries. Each term is searched independently; results are merged. Supports PubMed query syntax (e.g. `cancer AND immunotherapy[MeSH]`).

## `searchUrls` (type: `array`):

Paste full PubMed search URLs (e.g. `https://pubmed.ncbi.nlm.nih.gov/?term=cancer&filter=simsearch1.fha`). The actor extracts the query and merges with `searchTerms`.

## `pmidList` (type: `array`):

Direct-lookup mode: list of PubMed IDs to fetch without searching (e.g. `["38123456", "36438426"]`). Bypasses esearch — calls esummary + efetch directly. Combine with or use instead of `searchTerms`.

## `maxItemsPerTerm` (type: `integer`):

Cap on articles returned per search term. Total dataset size = sum across all terms.

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

Earliest publication date. PubMed format: `YYYY/MM/DD` (e.g. `2024/01/01`). Optional.

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

Latest publication date. PubMed format: `YYYY/MM/DD`. Optional.

## `articleType` (type: `string`):

Restrict to a specific article type. `any` keeps everything.

## `freeFullTextOnly` (type: `boolean`):

If true, restrict to articles with free full text available (PMC).

## `language` (type: `string`):

Restrict by article language.

## `journalFilter` (type: `string`):

Restrict to a specific journal (exact name, e.g. `Nature` or `New England Journal of Medicine`). Optional.

## `authorFilter` (type: `string`):

Restrict to articles by a specific author (PubMed author format, e.g. `Smith J` or `Smith JR`). Optional.

## `meshFilter` (type: `array`):

Restrict to articles tagged with these MeSH (Medical Subject Headings) terms. All terms are AND-ed (e.g. `["Lung Neoplasms", "Machine Learning"]` returns articles tagged with both).

## `affiliationFilter` (type: `string`):

Restrict to articles where any author's affiliation contains this substring (e.g. `Harvard`, `Mayo Clinic`, `Beijing`). Optional.

## `includeCitedByCount` (type: `boolean`):

Add a `citedByCount` field via NCBI elink (count of PubMed articles citing each result). Adds 1 elink call per page of PMIDs. Default off — turn on for citation-network analysis.

## `apiKey` (type: `string`):

Free key from https://www.ncbi.nlm.nih.gov/account/ — raises rate limit from 3 req/s to 10 req/s. Useful for large bulk runs.

## Actor input object example

```json
{
  "searchTerms": [
    "machine learning oncology"
  ],
  "searchUrls": [],
  "pmidList": [],
  "maxItemsPerTerm": 25,
  "articleType": "any",
  "freeFullTextOnly": false,
  "language": "any",
  "meshFilter": [],
  "includeCitedByCount": false
}
```

# 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 = {
    "searchTerms": [
        "machine learning oncology"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/pubmed-search-scraper").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 = { "searchTerms": ["machine learning oncology"] }

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/pubmed-search-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "machine learning oncology"
  ]
}' |
apify call crawlerbros/pubmed-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/pubmed-search-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "PubMed Search Scraper",
        "description": "Search PubMed (NCBI E-utilities) for biomedical articles by keyword, date range, and article type. Returns title, authors, journal, abstract, DOI, MeSH terms, keywords, and citation. Free public API, no proxy, no cookies. Optional NCBI API key for higher rate limits.",
        "version": "0.1",
        "x-build-id": "hcjhKD8omSadVHcxr"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/crawlerbros~pubmed-search-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-crawlerbros-pubmed-search-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/crawlerbros~pubmed-search-scraper/runs": {
            "post": {
                "operationId": "runs-sync-crawlerbros-pubmed-search-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/crawlerbros~pubmed-search-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-crawlerbros-pubmed-search-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchTerms": {
                        "title": "Search terms",
                        "type": "array",
                        "description": "One or more PubMed search queries. Each term is searched independently; results are merged. Supports PubMed query syntax (e.g. `cancer AND immunotherapy[MeSH]`).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchUrls": {
                        "title": "PubMed search URLs (optional)",
                        "type": "array",
                        "description": "Paste full PubMed search URLs (e.g. `https://pubmed.ncbi.nlm.nih.gov/?term=cancer&filter=simsearch1.fha`). The actor extracts the query and merges with `searchTerms`.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "pmidList": {
                        "title": "PMID list (optional)",
                        "type": "array",
                        "description": "Direct-lookup mode: list of PubMed IDs to fetch without searching (e.g. `[\"38123456\", \"36438426\"]`). Bypasses esearch — calls esummary + efetch directly. Combine with or use instead of `searchTerms`.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxItemsPerTerm": {
                        "title": "Max items per search term",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Cap on articles returned per search term. Total dataset size = sum across all terms.",
                        "default": 25
                    },
                    "dateFrom": {
                        "title": "Publication date from (YYYY/MM/DD)",
                        "type": "string",
                        "description": "Earliest publication date. PubMed format: `YYYY/MM/DD` (e.g. `2024/01/01`). Optional."
                    },
                    "dateTo": {
                        "title": "Publication date to (YYYY/MM/DD)",
                        "type": "string",
                        "description": "Latest publication date. PubMed format: `YYYY/MM/DD`. Optional."
                    },
                    "articleType": {
                        "title": "Article type",
                        "enum": [
                            "any",
                            "review",
                            "clinical_trial",
                            "meta_analysis",
                            "case_report",
                            "randomized_controlled_trial",
                            "systematic_review",
                            "editorial",
                            "letter",
                            "comment",
                            "practice_guideline",
                            "observational_study",
                            "comparative_study",
                            "multicenter_study"
                        ],
                        "type": "string",
                        "description": "Restrict to a specific article type. `any` keeps everything.",
                        "default": "any"
                    },
                    "freeFullTextOnly": {
                        "title": "Free full-text only",
                        "type": "boolean",
                        "description": "If true, restrict to articles with free full text available (PMC).",
                        "default": false
                    },
                    "language": {
                        "title": "Language",
                        "enum": [
                            "any",
                            "english",
                            "spanish",
                            "french",
                            "german",
                            "chinese",
                            "japanese",
                            "italian",
                            "portuguese",
                            "russian",
                            "korean"
                        ],
                        "type": "string",
                        "description": "Restrict by article language.",
                        "default": "any"
                    },
                    "journalFilter": {
                        "title": "Journal name (optional)",
                        "type": "string",
                        "description": "Restrict to a specific journal (exact name, e.g. `Nature` or `New England Journal of Medicine`). Optional."
                    },
                    "authorFilter": {
                        "title": "Author (optional)",
                        "type": "string",
                        "description": "Restrict to articles by a specific author (PubMed author format, e.g. `Smith J` or `Smith JR`). Optional."
                    },
                    "meshFilter": {
                        "title": "MeSH terms (optional)",
                        "type": "array",
                        "description": "Restrict to articles tagged with these MeSH (Medical Subject Headings) terms. All terms are AND-ed (e.g. `[\"Lung Neoplasms\", \"Machine Learning\"]` returns articles tagged with both).",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "affiliationFilter": {
                        "title": "Author affiliation (optional)",
                        "type": "string",
                        "description": "Restrict to articles where any author's affiliation contains this substring (e.g. `Harvard`, `Mayo Clinic`, `Beijing`). Optional."
                    },
                    "includeCitedByCount": {
                        "title": "Include cited-by count",
                        "type": "boolean",
                        "description": "Add a `citedByCount` field via NCBI elink (count of PubMed articles citing each result). Adds 1 elink call per page of PMIDs. Default off — turn on for citation-network analysis.",
                        "default": false
                    },
                    "apiKey": {
                        "title": "NCBI API key (optional)",
                        "type": "string",
                        "description": "Free key from https://www.ncbi.nlm.nih.gov/account/ — raises rate limit from 3 req/s to 10 req/s. Useful for large bulk runs."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
