# Academic Papers API: OpenAlex, Crossref, arXiv for AI agents (`wooden_scanner_c1n/academic-research-search`) Actor

Search scholarly papers across OpenAlex, Crossref and arXiv in one run. Clean, DOI-deduplicated records with title, authors, year, venue, citations, open-access status and PDF/landing links. Open-licensed metadata, built for AI agents, RAG and literature reviews.

- **URL**: https://apify.com/wooden_scanner_c1n/academic-research-search.md
- **Developed by:** [Sean](https://apify.com/wooden_scanner_c1n) (community)
- **Categories:** AI, Developer tools, Other
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 paper returneds

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

## Academic Papers API: OpenAlex, Crossref, arXiv for AI agents

Search scholarly papers across **OpenAlex, Crossref and arXiv in a single run** and get back one clean record per paper, **deduplicated by DOI**: title, authors, year, venue, DOI, citation count, open-access status, PDF and landing-page links, and the licence.

Built for **AI agents, RAG pipelines, literature reviews, research assistants and academic dashboards** that need reliable paper metadata without juggling three APIs, their rate limits and their different formats.

### Why use it

- **Three open databases, one format.** OpenAlex (250M+ works with citations and open-access data), Crossref (the DOI registry) and arXiv (preprints) come back in the same fields.
- **No duplicates.** The same paper found in two or three sources is merged into one record, keeping the best data from each (for example, OpenAlex citations plus the arXiv PDF). Preprints are matched to their published version by DOI, arXiv ID or title and year.
- **Open-access aware.** Filter to free-to-read papers and get a direct PDF link where one is openly available.
- **Licence-clean.** Only openly licensed metadata. No full texts are copied, and abstracts are only included where the licence allows it (arXiv, CC0). Every record carries its licence and source attribution.
- **Agent-ready.** One query in, predictable JSON out. Works through the Apify API and the **Apify MCP server**, so Claude, ChatGPT, Cursor and other MCP clients can call it as a tool.
- **Fast.** A typical search returns in under 15 seconds.

### Input

| Field | What it does |
|---|---|
| `query` | Keywords searched in titles and abstracts (required). |
| `sources` | `openalex`, `crossref`, `arxiv`. Default: all three. |
| `yearFrom` / `yearTo` | Publication year range (optional). |
| `openAccessOnly` | Only free-to-read papers (default off). |
| `sort` | `relevance` (default), `citations` (most cited first) or `newest`. |
| `maxItems` | Maximum unique papers to return, 1–500 (default 20). |
| `includeAbstracts` | Add abstracts for arXiv papers (default off). |
| `openAlexApiKey` | Optional free OpenAlex key for your own daily quota. |
| `contactEmail` | Optional email for Crossref's faster "polite" pool. |

```json
{
  "query": "retrieval augmented generation",
  "sources": ["openalex", "crossref", "arxiv"],
  "yearFrom": 2022,
  "openAccessOnly": true,
  "sort": "citations",
  "maxItems": 50
}
```

Advanced: arXiv field syntax such as `cat:cs.CL AND ti:retrieval` is passed straight to arXiv.

### Output

One record per unique paper:

```json
{
  "title": "Attention Is All You Need",
  "authors": ["Ashish Vaswani", "Noam Shazeer", "Niki Parmar", "Jakob Uszkoreit", "Llion Jones", "Aidan N. Gomez", "Łukasz Kaiser", "Illia Polosukhin"],
  "authorCount": 8,
  "year": 2017,
  "publicationDate": "2017-06-12",
  "venue": "arXiv (Cornell University)",
  "publisher": null,
  "type": "preprint",
  "doi": "10.48550/arxiv.1706.03762",
  "doiUrl": "https://doi.org/10.48550/arxiv.1706.03762",
  "arxivId": "1706.03762",
  "openAlexId": "W2626778328",
  "citations": 122093,
  "isOpenAccess": true,
  "oaStatus": "green",
  "pdfUrl": "https://arxiv.org/pdf/1706.03762",
  "landingUrl": "https://arxiv.org/abs/1706.03762",
  "abstract": null,
  "licence": null,
  "source": "OpenAlex",
  "sources": ["OpenAlex", "arXiv"],
  "metadataLicence": "Metadata from OpenAlex (openalex.org), CC0 1.0. Metadata from arXiv.org, CC0 1.0. Thank you to arXiv for use of its open access interoperability.",
  "retrievedAt": "2026-11-03T20:30:00Z",
  "query": "attention is all you need"
}
```

Field notes:

- `citations` comes from OpenAlex or Crossref (the higher of the two when both have it). arXiv has no citation counts, so arXiv-only papers show `null`.
- `isOpenAccess` is `true` when OpenAlex flags the paper as open access, Crossref shows a Creative Commons licence, or the paper is on arXiv. `null` means unknown, not closed.
- `licence` is the paper's own licence where a source records it (for example `cc-by` or a Creative Commons URL).
- `authors` lists up to 50 names; `authorCount` gives the full number.
- `pdfUrl` and `landingUrl` are links only. The Actor never downloads or redistributes full texts.

### Pricing

Pay per result: a small fee when the run starts and a fee per unique paper returned. Duplicates merged across sources are counted once. No subscription. Set a maximum cost per run in the run options and the Actor stops when it reaches it.

### Data sources and licences

| Source | What it adds | Licence / terms |
|---|---|---|
| [OpenAlex](https://openalex.org) | Citations, open-access status, venues, PDF locations | All data CC0 ([pricing & licence](https://help.openalex.org/access/pricing/)) |
| [Crossref REST API](https://api.crossref.org) | DOI registry metadata, licences | "Almost none of the metadata is subject to copyright, and you may use it for any purpose" ([docs](https://www.crossref.org/documentation/retrieve-metadata/rest-api/)) |
| [arXiv API](https://info.arxiv.org/help/api/index.html) | Preprints, categories, abstracts | Descriptive metadata CC0 ([API terms](https://info.arxiv.org/help/api/tou.html)) |

Thank you to arXiv for use of its open access interoperability. This Actor is not endorsed by OpenAlex, Crossref or arXiv. It uses each API as documented, identifies itself with a descriptive User-Agent and respects each rate limit (arXiv: one request every three seconds).

### Good to know

- **OpenAlex quota.** Without a key, OpenAlex shares a small free daily quota per network. If it runs out, the run carries on with Crossref and arXiv and says so in the log. Add your own free OpenAlex key in the input to avoid this.
- **Open access on Crossref** is inferred from a Creative Commons licence, so with `openAccessOnly` some open papers without a recorded licence are left out.
- **Sorting.** Crossref and arXiv results are always the most relevant matches, then sorted the way you ask; OpenAlex sorts its title-and-abstract matches directly.
- Up to 500 papers per run. For larger pulls, split by year range.
- Abstracts from OpenAlex and Crossref are not included, because publishers or authors may hold copyright in them.

### Use with AI agents (MCP)

Add this Actor to the Apify MCP server (`https://mcp.apify.com`) and your agent can call it as a tool: pass a `query`, optionally `yearFrom`, `openAccessOnly` and `sort`, and read back the JSON records. Keep `maxItems` small (10–20) for fast, cheap agent calls.

# Actor input Schema

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

Keywords to search for in paper titles and abstracts, e.g. 'large language models' or 'CRISPR gene editing'. Advanced: arXiv field syntax such as 'cat:cs.CL AND ti:retrieval' is passed straight to arXiv.

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

Which open databases to search. Leave empty for all three.

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

Only papers published in or after this year.

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

Only papers published in or before this year.

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

Only return papers that are free to read (OpenAlex OA flag, a Creative Commons licence on Crossref, or arXiv).

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

Relevance mixes the best matches from each source. Citations puts the most-cited first (citation counts come from OpenAlex and Crossref; arXiv has none). Newest puts the latest publications first.

## `maxItems` (type: `integer`):

Maximum number of unique papers to return (after removing duplicates). You pay per paper returned.

## `includeAbstracts` (type: `boolean`):

Adds the abstract for arXiv papers (arXiv metadata is CC0). Abstracts from other sources are never included because publishers may hold copyright in them.

## `openAlexApiKey` (type: `string`):

Optional. Without a key, OpenAlex shares a small free daily quota per network. A free key from openalex.org/settings/api gives you your own quota. If the shared quota runs out, the run continues with Crossref and arXiv.

## `contactEmail` (type: `string`):

Optional. Sent to Crossref as the 'mailto' parameter, which puts requests in Crossref's faster 'polite' pool and lets Crossref contact you about problems.

## Actor input object example

```json
{
  "query": "large language models",
  "sources": [
    "openalex",
    "crossref",
    "arxiv"
  ],
  "openAccessOnly": false,
  "sort": "relevance",
  "maxItems": 20,
  "includeAbstracts": false
}
```

# Actor output Schema

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

All paper records returned by the run.

# 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 models"
};

// Run the Actor and wait for it to finish
const run = await client.actor("wooden_scanner_c1n/academic-research-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 = { "query": "large language models" }

# Run the Actor and wait for it to finish
run = client.actor("wooden_scanner_c1n/academic-research-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 '{
  "query": "large language models"
}' |
apify call wooden_scanner_c1n/academic-research-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,wooden_scanner_c1n/academic-research-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/AKGwybWkU5mRatYfR/builds/a2l2JydCYwMdBAeJd/openapi.json
