# Scholarly Literature Search: 4 Open Databases (`jetlaunch/scholarly-literature-search`) Actor

Search OpenAlex, Crossref, PubMed and arXiv in one call, look up a single record, or map its citations. Results are merged by DOI.

- **URL**: https://apify.com/jetlaunch/scholarly-literature-search.md
- **Developed by:** [Chris O'Byrne](https://apify.com/jetlaunch) (community)
- **Categories:** AI, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 literature searches

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

## Scholarly Literature Search: 4 Open Databases

Scholarly Literature Search queries **OpenAlex, Crossref, PubMed and arXiv** with one input and returns one clean list of papers. Records that appear in more than one source are merged by DOI (and by arXiv id, PubMed ID or OpenAlex id), so you see each paper once with the best available metadata. It also looks up a single record by identifier and lists the works a paper cites and the works that cite it. It uses only the official public APIs of those four services.

It is built for researchers, librarians, analysts, and developers who feed literature into RAG pipelines, reading lists, systematic review screening, or citation analysis. It runs from the Console, the API, or any Apify integration, and it can be called as a tool by AI agents through the Apify MCP server.

### What it does

The Actor has three modes. Each run is one billable call.

- **Search**: keyword search across the sources you select, with an optional publication year range and a result limit up to 100. Results are merged, de-duplicated and ranked by reciprocal rank fusion across the sources.
- **Record detail**: look up one paper by DOI, PubMed ID, arXiv id or OpenAlex work id, and combine what every selected source knows about it.
- **Citation graph**: for one paper, return the paper itself, the works it cites (references) and the works that cite it, one level deep. Uses OpenAlex, with the Crossref reference list as a fallback for references.

#### How to try it

1. Open the Input tab. The default input searches for "retrieval augmented generation" and asks for 10 results.
2. Click Start. The Output tab shows a table of papers.
3. Switch the mode to Record detail or Citation graph and paste a DOI, such as 10.1371/journal.pdig.0000877.

### Input

| Field | Used in | Description |
|---|---|---|
| mode | all | search, record-detail or citation-graph |
| query | search | Keywords. Use double quotes for an exact phrase on arXiv. |
| sources | search, record-detail | Any of openalex, crossref, pubmed, arxiv. Default is all four. |
| yearFrom, yearTo | search | Publication year bounds. |
| maxResults | search | 1 to 100, default 10. |
| identifier | record-detail, citation-graph | DOI, PubMed ID, arXiv id or OpenAlex work id. |
| maxReferences, maxCitingWorks | citation-graph | How many references (up to 200) and citing works (up to 100) to return. |
| openalexApiKey | all, optional | Your own free OpenAlex key. See the OpenAlex note below. |

Example input:

```json
{
    "mode": "search",
    "query": "retrieval augmented generation",
    "sources": ["openalex", "crossref", "pubmed", "arxiv"],
    "yearFrom": 2020,
    "maxResults": 10
}
```

### Output

Each record has: title, authors (as given in the source metadata, at most 100), author count, venue, year, type, DOI, citation count and its source, open access URL, source identifiers (OpenAlex id, PubMed ID, PubMed Central id, arXiv id), a link, and the list of sources that returned it. Search results also carry a rank. Citation graph rows carry a relation field (root, reference or cited_by). A SUMMARY record in the key-value store lists which sources answered, any warnings, and the licence notices.

Abstracts are returned only for records that come from arXiv. See Data sources and licences below.

```json
{
    "rank": 1,
    "title": "Retrieval augmented generation for large language models in healthcare: A systematic review",
    "authors": ["Lameck Mbangula Amugongo", "Pietro Mascheroni", "Steven Brooks"],
    "author_count": 5,
    "venue": "PLOS Digital Health",
    "year": 2025,
    "type": "journal-article",
    "doi": "10.1371/journal.pdig.0000877",
    "citation_count": 255,
    "citation_count_source": "openalex",
    "open_access_url": "https://doi.org/10.1371/journal.pdig.0000877",
    "openalex_id": "W4411203672",
    "pmid": "40498738",
    "pmcid": "PMC12157099",
    "url": "https://doi.org/10.1371/journal.pdig.0000877",
    "sources": ["crossref", "openalex", "pubmed"]
}
```

### Pricing

Pay per event. You pay for each call, not per record, and you are not charged when a run returns nothing or fails.

| Event | Price | What counts as one event |
|---|---|---|
| search | $0.02 | One search run that returns at least one record |
| record-detail | $0.01 | One record lookup that finds the record |
| citation-graph | $0.04 | One citation graph run that returns at least one reference or citing work |

A search for 100 records costs the same $0.02 as a search for 10. Platform compute for a typical run is a fraction of a cent. A run's maximum cost can be capped in the run options.

### Data sources and licences

- **OpenAlex** (api.openalex.org): data is released under CC0.
- **Crossref** (api.crossref.org): bibliographic metadata is open and may be used for any purpose. Crossref notes that some abstracts may be copyrighted by publishers or authors, so no Crossref abstract is returned.
- **PubMed** (NCBI E-utilities): provided by the U.S. National Library of Medicine. NLM does not claim copyright on PubMed abstracts, but journal publishers or authors may, so no PubMed abstract is returned. See the NCBI Disclaimer and Copyright notice at https://www.ncbi.nlm.nih.gov/home/about/policies/ .
- **arXiv** (export.arxiv.org): descriptive metadata, including abstracts, is available under CC0. E-print files are not downloaded or stored; links point to arxiv.org. Thank you to arXiv for use of its open access interoperability.

The Actor is not affiliated with or endorsed by OpenAlex, Crossref, NCBI, the National Library of Medicine, or arXiv. It follows their published limits: one arXiv request per three seconds on a single connection, under three NCBI requests per second with the tool and email parameters sent, and the Crossref polite pool with a contact address.

### FAQ

#### Why are there no abstracts for most records?

Only arXiv explicitly releases abstracts as CC0. Other sources warn that abstracts can be under publisher or author copyright, so the Actor leaves them out rather than redistribute them.

#### Why did OpenAlex return nothing?

OpenAlex now gives requests without an API key a small daily budget that is shared by everyone on the same network address. On a shared platform that budget is often used up. The run does not fail when other sources answer; the SUMMARY record shows the OpenAlex error. Single record lookups on OpenAlex are free, but search, reference lists and citing works are not. Create a free key at openalex.org/settings/api-key, paste it in the OpenAlex API key field, and OpenAlex requests use your own daily budget. Citation graph mode depends on OpenAlex, so it needs this in most cases.

#### How are duplicates handled?

Records are joined when they share a DOI, arXiv id, PubMed ID or OpenAlex id. Records with no identifier are joined only when title and year match exactly after normalization.

#### Why do author names look different between records?

Authors are reported as the selected source gives them. For merged records the Actor prefers Crossref, then arXiv, then OpenAlex, then PubMed. PubMed supplies last name and initials only.

#### Is citation count the same everywhere?

No. The count comes from OpenAlex when available, otherwise Crossref, and the field citation_count_source says which. arXiv and PubMed supply no count here.

### Limitations

- Search relevance is each source's own ranking, combined; it is not a systematic review tool and does not replace a database licence.
- PubMed search uses PubMed's own query handling. Date filters use the publication date.
- arXiv responses are sometimes slow; a search with arXiv selected can take 30 seconds or more.
- Citation graph is depth 1 only. Crossref cannot list citing works, so citing works come from OpenAlex only.
- Identifier look-ups are only as accurate as the upstream data. If two sources disagree about which paper an identifier belongs to, the Actor drops the record whose title does not match and notes it in the SUMMARY.

### Support

Found a bug or a field that looks wrong? Open an issue in the Issues tab of this Actor with the run link and the input. For custom needs, contact chris@jetlaunch.net.

# Actor input Schema

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

search: find papers by keyword across the selected sources and merge duplicates by DOI. record-detail: look up one paper by DOI, PubMed ID, arXiv id or OpenAlex id. citation-graph: list the works one paper cites and the works that cite it (depth 1, uses OpenAlex).

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

Keywords or a phrase, for example retrieval augmented generation. Put the phrase in double quotes to require an exact phrase on arXiv.

## `sources` (type: `array`):

Which sources to query. Leave all four selected for the widest coverage. A source that is temporarily unavailable is skipped and reported in the run summary.

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

Only return records published in or after this year. Leave empty for no lower bound.

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

Only return records published in or before this year. Leave empty for no upper bound.

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

Maximum number of unique records to return. Each source is asked for this many records before merging. A search call is billed once, whatever the number of records.

## `identifier` (type: `string`):

A DOI (10.1000/xyz or a doi.org link), a PubMed ID (digits), an arXiv id (2005.11401 or arXiv:2005.11401) or an OpenAlex work id (W2741809807).

## `maxReferences` (type: `integer`):

How many of the paper's cited references to return.

## `maxCitingWorks` (type: `integer`):

How many works that cite the paper to return, most cited first.

## `openalexApiKey` (type: `string`):

OpenAlex now gives keyless callers a small daily budget that is shared by everyone on the same network address. If OpenAlex results come back empty or the run summary reports a budget error, paste your own free key from openalex.org/settings/api-key. The key is only sent to api.openalex.org.

## Actor input object example

```json
{
  "mode": "search",
  "query": "retrieval augmented generation",
  "sources": [
    "openalex",
    "crossref",
    "pubmed",
    "arxiv"
  ],
  "maxResults": 10,
  "maxReferences": 25,
  "maxCitingWorks": 25
}
```

# Actor output Schema

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

One row per unique paper (search), one record (record detail), or the root plus references and citing works (citation graph).

## `summary` (type: `string`):

Per-source status, warnings, charged event and licence notices.

# 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 = {
    "mode": "search",
    "query": "retrieval augmented generation",
    "sources": [
        "openalex",
        "crossref",
        "pubmed",
        "arxiv"
    ],
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jetlaunch/scholarly-literature-search").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "search",
    "query": "retrieval augmented generation",
    "sources": [
        "openalex",
        "crossref",
        "pubmed",
        "arxiv",
    ],
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jetlaunch/scholarly-literature-search").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "mode": "search",
  "query": "retrieval augmented generation",
  "sources": [
    "openalex",
    "crossref",
    "pubmed",
    "arxiv"
  ],
  "maxResults": 10
}' |
apify call jetlaunch/scholarly-literature-search --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/YCEGV8oidHcpvpWzg/builds/WpIdMqbXB0HOBzB1W/openapi.json
