# Academic Papers API: OpenAlex & Crossref Search (`yourevenings/academic-papers-api`) Actor

Search research paper metadata across OpenAlex and Crossref in one run: topic search, DOI lookup or author/ORCID, deduplicated by DOI, with citation counts, open access links and openly licensed abstracts. No API key. Not affiliated with OpenAlex or Crossref.

- **URL**: https://apify.com/yourevenings/academic-papers-api.md
- **Developed by:** [Your Evenings](https://apify.com/yourevenings) (community)
- **Categories:** AI, Developer tools, Education
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 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.
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

## Academic Papers API: OpenAlex & Crossref Search

**Academic Papers API** searches **OpenAlex and Crossref in one run** and returns research paper metadata as clean JSON rows, **deduplicated by DOI**, with authors and ORCID iDs, citation counts, open access status, PDF links and openly licensed abstracts. **No API key needed.** Three modes:

- **Topic search**: keywords such as `CRISPR gene editing` or `"large language models"`, with year and open access filters.
- **DOI lookup**: full metadata and citation counts for a list of up to 500 DOIs.
- **Author search**: an author's papers by name or ORCID iD, sorted by newest or most cited.

Turn on **monitor mode** and schedule the Actor to get only papers you haven't seen before, for a topic or an author.

Use it as a **research paper search API**, **OpenAlex API** or **Crossref API** for **literature search**, systematic reviews, citation analysis and AI research agents. Export as CSV, JSON or Excel.

> **Not affiliated with any data source.** This Actor is independent and is not affiliated with or endorsed by OpenAlex/OurResearch or Crossref. It reads their public APIs.

### Why use this academic papers API?

- **Two databases, one schema.** OpenAlex (all disciplines, including arXiv preprints and PubMed-indexed papers) and Crossref (the DOI registry) return the same fields, so you don't write two integrations.
- **One row per paper.** The same paper found in several sources is merged into one row (matched by DOI, or exact title and year), and `foundIn` lists the sources. You pay once per paper.
- **Citation counts and open access links for every paper.** Papers found only in Crossref are looked up in OpenAlex by DOI (one batched request per 50 papers) to add citation counts, open access status and free-to-read links.
- **Author search that checks names.** OpenAlex picks its best-matching author profile (shown in the run SUMMARY); Crossref results are kept only when an author has the same family name and first initial.
- **Pay per paper returned.** Invalid DOIs, DOIs not found, source errors and notes are free status rows. The only other charges are the small Actor start fee and, in monitor mode, one fee per run that finds new papers.
- **Abstracts only where the licence allows.** An abstract is returned only when an openly available version of the paper carries a CC0, CC BY, CC BY-SA or public-domain licence (shown in `abstractLicence`). Otherwise `abstractStatus` says why it was left out.
- **Polite to the sources.** Each source is paced separately and identified with a contact address.

### How do I search academic papers? Quick start

Press **Start** with the prefilled input, or paste this into the **JSON** view of the Input tab. It returns up to 25 papers about CRISPR gene editing published since 2023, from both sources.

```json
{
  "mode": "search",
  "query": "CRISPR gene editing",
  "yearFrom": 2023,
  "maxResultsPerSource": 10,
  "maxResults": 25
}
```

In our test run on 1 November 2026 it read 20 records from the two sources, merged 1 duplicate and returned 19 papers in about 2.4 seconds (3 API requests). 9 papers found only in Crossref got citation counts from OpenAlex. 5 of the 19 came with an abstract under an open licence.

Look up DOIs (with or without `https://doi.org/`):

```json
{
  "mode": "doi",
  "dois": ["10.1126/science.1225829", "10.1038/nature14539", "10.48550/arXiv.1706.03762"]
}
```

An author's most cited papers:

```json
{
  "mode": "author",
  "author": "Jennifer A. Doudna",
  "sortBy": "mostCited",
  "maxResults": 20
}
```

Put a phrase in double quotes (`"\"base editing\""`) to keep only papers with that exact phrase in the title or abstract.

### Who it's for

- **Researchers, librarians and students** running literature searches and systematic reviews across databases.
- **Data and analytics teams** building citation, bibliometric or research-trend datasets.
- **AI and RAG developers** who need clean metadata and open access PDF links for research agents.
- **Science publishers, funders and biotech or pharma teams** tracking new papers on a topic, a drug or a researcher.

### What can I do with academic paper data?

1. **Literature search across databases.** One query, two sources, duplicates merged, ready for screening.
2. **DOI list enrichment.** Add titles, authors, venues, citation counts, open access links and retraction flags to a reference list.
3. **New-paper alerts.** A topic or author with `monitorMode` on, sorted by newest, on a weekly schedule.
4. **Author publication lists.** Every paper for an ORCID iD, newest first, with co-authors and affiliations.
5. **Open access finder.** `openAccessOnly` with `oaUrl` and `pdfUrl` to collect free full texts.

### What does the output look like?

Rows from the DOI lookup test run on 1 November 2026 (citation counts from OpenAlex on that day):

| Year | Title | Venue | Cited by | Open access | Found in |
|---|---|---|---|---|---|
| 2017 | Attention Is All You Need | arXiv (Cornell University) | 120,297 | green | OpenAlex |
| 2015 | Deep learning | Nature | 84,126 | green | OpenAlex, Crossref |
| 2020 | Array programming with NumPy | Nature | 23,826 | hybrid | OpenAlex, Crossref |
| 2012 | A Programmable Dual-RNA–Guided DNA Endonuclease in Adaptive Bacterial Immunity | Science | 17,116 | green | OpenAlex, Crossref |

The same run returned a free `invalid_doi` row for `not-a-doi` and a free `not_found` row for a DOI no source knew. Of the four papers, only *Array programming with NumPy* (CC BY) came with its abstract.

One row, shortened:

```json
{
  "rowType": "paper",
  "paperId": "doi:10.1038/nature14539",
  "doi": "10.1038/nature14539",
  "title": "Deep learning",
  "authors": [{ "name": "Yann LeCun", "orcid": "0000-0002-1992-2684", "affiliations": ["Meta (United States)", "New York University"] }, "..."],
  "authorCount": 3,
  "publicationYear": 2015,
  "venue": "Nature",
  "isOpenAccess": true,
  "oaStatus": "green",
  "citedByCount": 84126,
  "citedByCountSource": "OPENALEX",
  "ids": { "doi": "10.1038/nature14539", "openalex": "W2919115771", "pmid": "26017442", "pmcid": null, "arxiv": null },
  "abstract": null,
  "abstractStatus": "none_at_source",
  "abstractLicence": null,
  "foundIn": ["OPENALEX", "CROSSREF"],
  "enrichedFrom": [],
  "url": "https://doi.org/10.1038/nature14539"
}
```

### Input: how do I filter academic papers?

#### Mode (`mode`)

`search` (topic search), `doi` (DOI lookup) or `author` (author search).

#### Search query (`query`)

Keywords for topic search, e.g. `microplastics drinking water`. Quoted phrases (`"base editing"`) must appear in the title or abstract: the sources match quotes loosely, so the Actor checks each phrase itself and reads extra results to make up for the ones it drops.

#### DOIs (`dois`)

Up to 500 DOIs, one per line, with or without `https://doi.org/`. arXiv DOIs (`10.48550/arXiv.…`) work too.

#### Author name or ORCID iD (`author`)

A full name (`Jennifer A. Doudna`) or an ORCID iD (`0000-0001-9161-999X`). ORCID iDs search both sources.

#### Sources (`sources`)

`OPENALEX`, `CROSSREF` or both. Default: both.

#### Published from / to (`yearFrom`, `yearTo`)

Publication year range, applied by each source.

#### Open access only (`openAccessOnly`)

Only papers known to be free to read. Papers with unknown status are left out.

#### Sort by (`sortBy`)

`relevance` (default), `newest` or `mostCited`.

#### Maximum papers returned (`maxResults`)

Most paper rows returned and charged per run, after merging. Default 50; `0` means no limit (up to 10,000).

#### Maximum papers read per source (`maxResultsPerSource`)

How many results to read from each source before merging (1 to 1,000, default 25). Reading isn't charged; you pay per paper row returned.

#### Merge duplicates across sources (`deduplicate`)

On by default. Turn off to get one row per source record.

#### Add OpenAlex citation counts and open access links (`enrichWithOpenAlex`)

On by default. Fills citation counts and open access links for papers found only in Crossref. `enrichedFrom` shows when it was used.

#### Include openly licensed abstracts (`includeAbstract`)

On by default. An abstract is returned only when an openly available version of the paper carries a CC0, CC BY, CC BY-SA or public-domain licence. Many abstracts may be under the publisher's or author's copyright, so many rows have no abstract; `abstractStatus` says why. Turn off if you only need metadata.

#### Your OpenAlex API key (`openAlexApiKey`, optional)

Not needed. Without a key, OpenAlex shares a small daily allowance per network; for large or frequent runs, paste your own free OpenAlex key. It is stored as a secret input and never written to the output.

#### Monitor mode (`monitorMode`), first run (`emitBaselineOnFirstRun`), state store (`stateStoreName`)

See [How do I get alerts for new papers?](#how-do-i-get-alerts-for-new-papers).

### Output: what fields does each paper have?

| Field | What it is |
|---|---|
| `rowType` | `paper`, or `status` for free status rows |
| `paperId` | Stable ID: `doi:…` or `openalex:…` |
| `doi`, `ids` | DOI, plus OpenAlex, PubMed, PMC and arXiv IDs |
| `title` | Title |
| `abstract`, `abstractSource`, `abstractLicence` | Abstract (openly licensed papers only), which source it came from, and the licence it is shared under |
| `abstractStatus` | `included_open_licence`, `withheld_copyright` (the source has an abstract but the licence doesn't allow sharing it), `none_at_source` or `not_requested` |
| `authors`, `authorCount` | Names in order, ORCID iDs where published, affiliations |
| `publicationYear`, `publicationDate` | Year and date |
| `venue`, `publisher`, `type`, `language` | Journal or repository, publisher, work type, language |
| `isOpenAccess`, `oaStatus`, `oaUrl`, `pdfUrl`, `paperLicence` | Open access status, free-to-read links and the paper's licence |
| `citedByCount`, `citedByCountSource`, `referencesCount` | Citations (OpenAlex, else Crossref) and references |
| `subjects` | Topics and keywords |
| `isRetracted` | `true` when a source flags a retraction |
| `url` | DOI link or source page |
| `foundIn`, `enrichedFrom` | Sources that returned the paper; sources used only to add details |
| `changeType` | `new` in monitor mode |
| `licence`, `attribution` | Licence and attribution for each source used |
| `retrievedAt` | When the run read the data |

**Status** rows (free): `invalid_doi`, `not_found`, `note`, `source_error`, `no_matches`, `no_new_papers` or `budget_reached`, each with a plain-English `message`. If one source fails, rows from the others are kept.

The **SUMMARY** record in the default key-value store lists records read per source, duplicates merged, the matched author profile, request counts and the run time. The dataset has views for Overview, Open access links and Status rows.

### How do I get alerts for new papers?

Set `monitorMode` to `true`, `sortBy` to `newest`, and schedule a saved task (weekly suits most topics). The Actor remembers the papers it has returned in the named key-value store `stateStoreName` and returns only papers it hasn't returned before, marked `changeType: "new"`. In our test on 1 November 2026, the second run of the same monitor returned no papers, one free `no_new_papers` row and no charges beyond the Actor start fee.

- `emitBaselineOnFirstRun` (default `true`) returns current matches on the first run. Set it to `false` to remember them silently, with no paper charges.
- Use a different `stateStoreName` for each topic or author.

### Data sources, licences and attribution

Every row carries `licence` and `attribution` for the sources used. Rows are normalised by this Actor (field names, merged duplicates, contact details removed), so they are modified from the source records. Abstracts are shared only under the paper's own open licence, shown in `abstractLicence`.

| Source | API | Licence or terms | Attribution |
|---|---|---|---|
| OpenAlex | [OpenAlex API](https://developers.openalex.org/) | CC0 (public domain) | Source: OpenAlex (openalex.org), CC0. |
| Crossref | [Crossref REST API](https://www.crossref.org/documentation/retrieve-metadata/rest-api/) | Crossref says almost none of its metadata is subject to copyright; some abstracts may be subject to the publisher's or author's copyright, so they are returned only under an open licence | Source: Crossref REST API. |

None of the sources endorses this Actor. Paper PDFs are linked, not downloaded or copied.

### Published research metadata, no contact details

Rows hold published scholarly metadata: titles, venues, openly licensed abstracts and author names, ORCID iDs and affiliations as the authors published them. Email addresses and phone numbers are removed from abstracts and affiliations. Use author data for research, citation and discovery, in line with the data protection rules that apply to you.

### What are the limits?

- **Sources:** OpenAlex and Crossref only (no Google Scholar, Semantic Scholar or Scopus). arXiv preprints and PubMed-indexed papers are found through OpenAlex, not read from arXiv or PubMed directly.
- **Abstracts:** only for papers under CC0, CC BY, CC BY-SA or a public-domain licence.
- **Results:** up to 1,000 read per source and 10,000 returned per run. Topic search relevance is each source's own ranking; the Actor interleaves the sources' best matches.
- **Citation counts** come from OpenAlex (or Crossref) and differ from other citation indexes.
- **Author search by name** depends on OpenAlex picking the right profile; check `matchedAuthor` in the SUMMARY, or use an ORCID iD.
- **OpenAlex without a key** has a small shared daily allowance and sometimes slows down requests without a key. Short slowdowns are retried; if the allowance runs out, the run adds a free `source_error` row, keeps rows from the other sources, and you can add your own key.
- **Pacing:** Crossref one request a second, OpenAlex 4 a second, with retries after server errors.

### How much does it cost to get academic papers?

Pay per event:

| Event | Price |
|---|---|
| Paper returned (one deduplicated row) | $0.002 |
| Alert run with new matches (monitor mode only, once per run that returns at least one new paper) | $0.01 |
| Actor start | $0.00005 |

Status rows and the SUMMARY record are free. A monitor run with nothing new costs only the Actor start fee. Higher Apify plans get lower prices (shown on the Pricing tab). Set **Maximum cost per run** in the run options: the Actor stops before going over it and adds a free `budget_reached` row.

### Use the academic papers API from code, spreadsheets or an AI agent

Run it with the Apify API or client libraries, schedule it, or connect it to Make, Zapier, Google Sheets or webhooks through Apify integrations. AI agents can call it through Apify's MCP server.

The examples below return at most 10 papers and set a maximum cost of $0.05 for the run. Read your API token from an environment variable (`APIFY_TOKEN`) rather than pasting it into code.

#### JavaScript (Node.js)

```js
// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yourevenings/academic-papers-api').call(
  { mode: 'search', query: 'CRISPR gene editing', yearFrom: 2023, maxResults: 10 },
  { maxTotalChargeUsd: 0.05 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
## pip install "apify-client>=3"
import os
from decimal import Decimal
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yourevenings/academic-papers-api").call(
    run_input={"mode": "search", "query": "CRISPR gene editing", "yearFrom": 2023, "maxResults": 10},
    max_total_charge_usd=Decimal("0.05"),
)
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)
```

#### HTTP API (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/yourevenings~academic-papers-api/run-sync-get-dataset-items?maxTotalChargeUsd=0.05" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "search", "query": "CRISPR gene editing", "yearFrom": 2023, "maxResults": 10}'
```

#### AI agents (MCP)

Add Apify's MCP server with just this Actor as a tool. On first connection your browser opens so you can sign in to Apify and approve access.

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=yourevenings/academic-papers-api"
    }
  }
}
```

### FAQ

**Do I need an API key?** No. Both sources are public. An OpenAlex key is optional, for large or frequent runs.

**Is this Google Scholar?** No. It searches OpenAlex and Crossref, which have public APIs. OpenAlex covers a similar range of disciplines.

**Why does a paper show fewer citations than elsewhere?** Each index counts citations from its own set of papers. `citedByCountSource` says which count you have.

**Why did a source return no rows?** A free status row explains it: no matches, a quoted phrase not found in titles or abstracts, or a source error.

**Why do some papers have no abstract?** Many abstracts may be under the publisher's or author's copyright. The Actor shares one only when an openly available version of the paper is under CC0, CC BY, CC BY-SA or public domain; `abstractStatus` tells you which case applies.

**Can I get full-text PDFs?** The Actor returns `pdfUrl` and `oaUrl` links to free versions where known. It doesn't download PDFs.

### Feedback

Found a problem or need a field? Open an issue on the Issues tab.

# Changelog

This Actor's version history is a separate document: https://apify.com/yourevenings/academic-papers-api/changelog.md

# Actor input Schema

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

<b>Topic search</b> finds papers matching your keywords. <b>DOI lookup</b> returns full metadata for a list of DOIs. <b>Author search</b> returns an author's papers by name or ORCID iD.

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

Keywords to search titles, abstracts and full text where the source supports it, e.g. <code>large language models</code> or <code>microplastics drinking water</code>. Used in topic search mode.

## `dois` (type: `array`):

One DOI per line, with or without <code>https://doi.org/</code>. Up to 500 per run. Invalid or unknown DOIs come back as free status rows.

## `author` (type: `string`):

A full name such as <code>Jennifer A. Doudna</code>, or an ORCID iD such as <code>0000-0001-9161-999X</code>. Names: OpenAlex picks its best-matching author profile (shown in the run SUMMARY); Crossref results are kept only when an author has the same family name and first initial. ORCID iDs search OpenAlex and Crossref.

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

Which databases to search. Results are merged and deduplicated by DOI. arXiv and PubMed are not queried directly (their API hosts' robots.txt disallow automated access); OpenAlex already indexes arXiv preprints and PubMed records, with arXiv and PubMed IDs.

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

Only papers published in or after this year, e.g. <code>2023</code>.

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

Only papers published in or before this year.

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

Return only papers known to be free to read (OpenAlex open access status, a Creative Commons licence on Crossref). Papers with unknown status are left out.

## `sortBy` (type: `string`):

<b>Relevance</b> interleaves each source's best matches. <b>Newest</b> sorts by publication date. <b>Most cited</b> sorts by citation count (OpenAlex, then Crossref).

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

Most paper rows returned (and charged) per run after merging. <code>0</code> means no limit (up to 10,000).

## `maxResultsPerSource` (type: `integer`):

How many results to read from each source before merging (topic and author search). Reading is free; you pay only for paper rows returned.

## `deduplicate` (type: `boolean`):

Merge the same paper found in several sources into one row (matched by DOI, arXiv ID, PubMed ID, or exact title and year). <code>foundIn</code> lists the sources.

## `enrichWithOpenAlex` (type: `boolean`):

For papers found only in Crossref, look up their DOIs in OpenAlex (one batched request per 50 papers) to add citation counts, open access status and links. <code>enrichedFrom</code> shows when this was used.

## `includeAbstract` (type: `boolean`):

Include the abstract only when the paper carries an open licence that allows reuse (CC0, CC BY, CC BY-SA or public domain). Other abstracts are copyrighted by publishers or authors and are left out; abstractStatus says which. Turn off for metadata only.

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

Not needed. OpenAlex works without a key but shares a small daily allowance per network. For large or frequent runs, paste your own free key from openalex.org. It is used only for your requests to OpenAlex and never stored in the output.

## `monitorMode` (type: `boolean`):

Remember what was returned and, on later runs, return only papers not returned before. Schedule the Actor (e.g. weekly, sorted by newest) to get new-paper alerts for a topic or author.

## `emitBaselineOnFirstRun` (type: `boolean`):

On the first monitor run, return the current papers (on) or just remember them silently (off), so later runs return only what is new.

## `stateStoreName` (type: `string`):

Named key-value store that remembers returned papers. Use a different name for each topic or author you monitor.

## Actor input object example

```json
{
  "mode": "search",
  "query": "CRISPR gene editing",
  "dois": [
    "10.1126/science.1225829",
    "10.1038/nature14539"
  ],
  "author": "Jennifer A. Doudna",
  "sources": [
    "OPENALEX",
    "CROSSREF"
  ],
  "openAccessOnly": false,
  "sortBy": "relevance",
  "maxResults": 25,
  "maxResultsPerSource": 10,
  "deduplicate": true,
  "enrichWithOpenAlex": true,
  "includeAbstract": true,
  "monitorMode": false,
  "emitBaselineOnFirstRun": true,
  "stateStoreName": "academic-papers-monitor"
}
```

# Actor output Schema

## `overview` (type: `string`):

Overview view of the dataset.

## `openAccess` (type: `string`):

Open access view of the dataset.

## `status` (type: `string`):

Status rows (free) view of the dataset.

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

SUMMARY record: sources read, duplicates merged, matched author, request counts and timings.

# 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": "CRISPR gene editing",
    "dois": [
        "10.1126/science.1225829",
        "10.1038/nature14539"
    ],
    "author": "Jennifer A. Doudna",
    "sources": [
        "OPENALEX",
        "CROSSREF"
    ],
    "maxResults": 25,
    "maxResultsPerSource": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("yourevenings/academic-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 = {
    "mode": "search",
    "query": "CRISPR gene editing",
    "dois": [
        "10.1126/science.1225829",
        "10.1038/nature14539",
    ],
    "author": "Jennifer A. Doudna",
    "sources": [
        "OPENALEX",
        "CROSSREF",
    ],
    "maxResults": 25,
    "maxResultsPerSource": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("yourevenings/academic-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 '{
  "mode": "search",
  "query": "CRISPR gene editing",
  "dois": [
    "10.1126/science.1225829",
    "10.1038/nature14539"
  ],
  "author": "Jennifer A. Doudna",
  "sources": [
    "OPENALEX",
    "CROSSREF"
  ],
  "maxResults": 25,
  "maxResultsPerSource": 10
}' |
apify call yourevenings/academic-papers-api --silent --output-dataset

```

## MCP server setup

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