# OpenAlex Scraper · Works, Authors, Institutions & Citations (`reapx/openalex-scraper`) Actor

Scrape scholarly works, papers, citations, authors, institutions, and open-access metadata from the OpenAlex API. Fast HTTP scraper charging per returned record with tiered pricing.

- **URL**: https://apify.com/reapx/openalex-scraper.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** Developer tools, Business, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 1,000 record 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## OpenAlex Scraper · Works, Authors, Institutions & Citations

**OpenAlex Scraper** allows you to extract scholarly works, academic papers, citation counts, authorships, institution affiliations, and open-access metadata directly from the public [OpenAlex API](https://openalex.org). Search millions of publications by topic, field of study, university institution, publication year, or citation threshold with zero API key required.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/openalex-scraper/](https://reapx.dev/data/openalex-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/openalex-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/openalex-scraper). Questions: reapxdev@proton.me

### What is OpenAlex Scraper?

OpenAlex Scraper fetches structured bibliographic and bibliometric data from OpenAlex's catalog of over 250 million scholarly works. Designed for researchers, data scientists, academic libraries, and automated AI agents, this actor returns rich academic metadata per paper without browser overhead.

### Features

- **Full-Text & Topic Search**: Search works by query keywords, abstracts, or subfields.
- **Concept & Field Filters**: Filter by OpenAlex Concept IDs (e.g., Computer Science, Artificial Intelligence, Quantum Computing).
- **Institution Affiliations**: Extract publications affiliated with specific universities and research institutions (e.g., Harvard, MIT, Stanford, Oxford).
- **Citation Counts & Rankings**: Sort publications by citation count or set minimum citation thresholds.
- **Open-Access Status**: Filter by Open Access (OA) availability, status (gold, green, hybrid, bronze, closed), and obtain direct PDF download links.
- **Polite API Integration**: Uses OpenAlex polite pool routing for fast, reliable data retrieval.

### How to Scrape OpenAlex Works

1. **Enter a Search Query**: Type a topic or search term (e.g., `machine learning`, `quantum computing`, `climate change`).
2. **Apply Optional Filters**: Filter by concept ID, institution ID, publication year, or open-access status.
3. **Set Citation Thresholds**: Optionally specify a minimum citation count or sort order (`relevance_score:desc`, `cited_by_count:desc`, `publication_date:desc`).
4. **Run the Scraper**: Receive structured JSON output in your Apify dataset.

### ⬇️ Input

| Parameter | Type | Default | Description |
|---|---|---|---|
| `query` | string | `"machine learning"` | Full-text search query across titles and abstracts. |
| `concept` | string | `""` | OpenAlex Concept ID (e.g. `C41008148` for Computer Science). |
| `institution` | string | `""` | OpenAlex Institution ID (e.g. `I136199984` for Harvard University). |
| `year` | string | `""` | Publication year (e.g. `2024`) or year range (e.g. `2020-2024`). |
| `open_access` | string | `""` | Filter Open Access availability (`"true"`, `"false"`, or empty). |
| `min_citations` | integer | `0` | Minimum citation count filter. |
| `sort` | string | `"relevance_score:desc"` | Sort order (`relevance_score:desc`, `cited_by_count:desc`, `publication_date:desc`). |
| `max_results` | integer | `50` | Maximum work records to retrieve (1-10000). |
| `mailto` | string | `"reapxdev@proton.me"` | Contact email for OpenAlex polite pool. |

### Exported Dataset Schema

Each returned item represents one academic work and includes the following fields:

- `paperId`: OpenAlex work identifier (W-id only, e.g. `W2939474406`).
- `doi`: Digital Object Identifier canonical URL.
- `title`: Publication title.
- `publicationYear`: Year of publication.
- `publicationDate`: ISO date string (YYYY-MM-DD).
- `type`: Publication type (e.g., `article`, `book-chapter`, `preprint`).
- `citedByCount`: Total citations recorded by OpenAlex.
- `isOpenAccess`: Boolean flag indicating Open Access availability.
- `oaStatus`: Open Access tier (gold, green, hybrid, bronze, closed).
- `authors`: Comma-separated author names.
- `primaryInstitution`: Primary institution affiliation of the lead author.
- `primaryTopic`: Main research topic or field.
- `openalexUrl`: Canonical OpenAlex work URL.
- `landingPageUrl`: Publisher landing page URL.
- `pdfUrl`: Direct link to open-access PDF file.
- `language`: Publication language code.

### ❓ FAQ

#### How do I find OpenAlex Concept IDs?

Concept IDs start with `C` followed by digits (e.g., `C41008148` for Computer Science, `C154945302` for Artificial Intelligence). You can search concepts via OpenAlex or leave the field blank to rely on text search.

#### How do I find OpenAlex Institution IDs?

Institution IDs start with `I` followed by digits (e.g., `I136199984` for Harvard University, `I63966007` for MIT).

#### Is an API key required to run this scraper?

No API key is required. OpenAlex provides free public API access. The scraper includes a polite pool email parameter for optimal rate limits.

***

*Unofficial - not affiliated with OpenAlex. Collects public data only. reapx. Contact reapxdev@proton.me.*

### 🧪 Example input

A real, runnable configuration — this is an actual input this Actor has run with.

```json
{
  "query": "computer science",
  "concept": "C41008148",
  "max_results": 50,
  "mailto": "reapxdev@proton.me"
}
```

### 📄 Sample output

One real row from a real run of this Actor, unedited.

```json
{
  "paperId": "W2101234009",
  "doi": "https://doi.org/10.48550/arxiv.1201.0490",
  "title": "Scikit-learn: Machine Learning in Python",
  "publicationYear": 2012,
  "publicationDate": "2012-01-02",
  "type": "preprint",
  "citedByCount": 63895,
  "isOpenAccess": true,
  "oaStatus": "green",
  "authors": "Fabián Pedregosa, Gaël Varoquaux, Alexandre Gramfort, Vincent Michel, Bertrand Thirion, Olivier Grisel, Mathieu Blondel, Müller, Andreas, Nothman, Joel, Louppe, Gilles, Peter Prettenhofer, Ron J. Weiss, Vincent Dubourg, Jake Vanderplas, Alexandre Passos, David Cournapeau, Matthieu Brucher, Matthieu Perrot, Édouard Duchesnay",
  "primaryInstitution": "Commissariat à l'Énergie Atomique et aux Énergies Alternatives",
  "primaryTopic": "Computational Physics and Python Applications",
  "openalexUrl": "https://openalex.org/W2101234009",
  "landingPageUrl": "http://arxiv.org/abs/1201.0490",
  "pdfUrl": "https://arxiv.org/pdf/1201.0490",
  "language": "en"
}
```

### How it works

1. You set the filters below, or none at all.
2. The Actor calls the source's own public endpoint and pages through the results.
3. Every row is pushed to the dataset **as it is built**, not buffered to the end — so a
   run that hits its time limit still returns everything it collected up to that point.
4. You are charged per row returned, so the maximum-results field is also your cost cap.

### 💬 Your feedback

Found a bug, or need a field this does not return yet? Open an issue on the Actor's **Issues**
tab, or write to **reapxdev@proton.me**. Bugs get fixed and reasonable field requests get
added.

### ⚠️ Run outcomes and error handling

This Actor reports what happened in the run's **status message**, and it always keeps whatever it collected. These are the outcomes you can get and what each one means.

| Outcome | What it means |
|---|---|
| **Success** | Rows were returned and you were charged `record-returned` at $0.002 per row. |
| **No matches** | The source returned nothing for your filters. **Nothing is charged.** Widen the date window or drop a filter. |
| **Partial - source refused** | The source rate-limited or refused some requests. The affected items are skipped and named in the log, and **everything already collected is still pushed**. A block never discards a run's work. |
| **Rejected filter** | The source itself rejected the filter combination. The run fails fast with the source's own reason and **nothing is charged.** |

#### What is guaranteed either way

- **Every row is pushed as it is built**, not buffered to the end of the run. Anything that buffers output loses everything to a timeout, a block or a migration; this does not.
- **A field absent from the source is absent from the row.** Nothing is inferred, modelled or filled in to make a row look complete.

# Actor input Schema

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

Full-text search query across titles, abstracts, and keywords (e.g. 'machine learning', 'quantum computing').

## `concept` (type: `string`):

OpenAlex Concept ID filter (e.g. 'C41008148' for Computer Science, 'C119857082' for Machine Learning).<br><br>Leave this field empty to skip this filter.

## `institution` (type: `string`):

OpenAlex Institution ID filter (e.g. 'I136199984' for Harvard University, 'I40347166' for University of Oxford).<br><br>Leave this field empty to skip this filter.

## `year` (type: `string`):

Filter by publication year (e.g. '2024') or year range (e.g. '2020-2024').<br><br>Leave this field empty to skip this filter.

## `open_access` (type: `string`):

Filter by Open Access availability ('true', 'false', or empty for all).<br><br>Options: <code></code>, <code>true</code>, <code>false</code>.

## `min_citations` (type: `integer`):

Filter works with at least this number of citations.

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

Sort order for results.<br><br>Options: <code>relevance\_score:desc</code>, <code>cited\_by\_count:desc</code>, <code>publication\_date:desc</code>.

## `max_results` (type: `integer`):

Maximum number of work records to return (1-10000).<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `mailto` (type: `string`):

Contact email sent to OpenAlex API polite pool for higher rate limits.

## Actor input object example

```json
{
  "query": "machine learning",
  "sort": "relevance_score:desc",
  "max_results": 50,
  "mailto": "reapxdev@proton.me"
}
```

# Actor output Schema

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

Every record found by this run, one row per item, in the default dataset.

# 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": "machine learning",
    "concept": "",
    "institution": "",
    "year": "",
    "open_access": "",
    "min_citations": 0,
    "sort": "relevance_score:desc",
    "max_results": 50,
    "mailto": "reapxdev@proton.me"
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/openalex-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 = {
    "query": "machine learning",
    "concept": "",
    "institution": "",
    "year": "",
    "open_access": "",
    "min_citations": 0,
    "sort": "relevance_score:desc",
    "max_results": 50,
    "mailto": "reapxdev@proton.me",
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/openalex-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 '{
  "query": "machine learning",
  "concept": "",
  "institution": "",
  "year": "",
  "open_access": "",
  "min_citations": 0,
  "sort": "relevance_score:desc",
  "max_results": 50,
  "mailto": "reapxdev@proton.me"
}' |
apify call reapx/openalex-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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