# Crossref Scraper · DOI Metadata, Authors, Journals & Citations (`reapx/crossref-scraper`) Actor

Scrape scholarly DOI metadata, works, journal articles, authors, citations, funding, and licenses from the Crossref REST API. Fast HTTP scraper with pay-per-event pricing.

- **URL**: https://apify.com/reapx/crossref-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)

## Crossref Scraper · DOI Metadata, Authors, Journals & Citations

**Crossref Scraper** is a high-speed, light-footprint HTTP actor designed to extract scholarly DOI metadata, journal articles, books, preprints, citation counts, author affiliations, funding agency records, and open-access licensing information directly from the official Crossref REST API (`api.crossref.org`).

> 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/crossref-scraper/](https://reapx.dev/data/crossref-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/crossref-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/crossref-scraper). Questions: reapxdev@proton.me

Maintained by reapX. Public source data transformed into addressable entity records. Archive & API access guarantees. Contact <reapxdev@proton.me>.

***

### Features & Capabilities

- **Complete DOI Metadata:** Extract digital object identifiers (`doi`), sanitized paper identifiers (`paperId`), article titles, publication dates, and publication types (`journal-article`, `book-chapter`, `proceedings-article`, `posted-content`, `dataset`).
- **Authors & Affiliations:** Collect full author lists, primary author affiliations, and author counts for every work.
- **Journals, Publishers & ISSNs:** Capture container titles, publisher names, volume, issue, page ranges, print/electronic ISSNs, and ISBNs.
- **Citations & References:** Retrieve citation counts (`isReferencedByCount`) and bibliography reference counts (`referenceCount`).
- **Funding & Licensing:** Track grant funding agency names (`funderNames`), funder registry DOIs (`funderIds`), open access status (`isOpenAccess`), and reuse license URLs (`licenseUrl`).
- **Direct PDF & Document Links:** Extract direct URLs to full text PDF documents and publisher landing pages whenever available.
- **Flexible Filters & Deep Paging:** Filter by keyword, author, title, journal, publisher member ID, date range, funder ID, license availability, or abstract presence.
- **Pay-Per-Event Pricing:** Charged strictly per returned record written to the default dataset. Empty searches, invalid queries, and rate-limited attempts cost zero.

***

### ⬇️ Input

The input configuration for Crossref Scraper allows you to filter and sort scholarly works across the entire Crossref catalog.

#### Input Parameters

| Parameter | Type | Required | Default / Example | Description |
| :--- | :--- | :--- | :--- | :--- |
| `query` | string | No | `10.1002` | Free-text search terms for matching metadata across titles, abstracts, and full texts. |
| `query_author` | string | No | `Doudna` | Filter works by author given or family name. |
| `query_title` | string | No | `deep learning` | Restrict search terms specifically to work titles. |
| `query_container_title` | string | No | `The CRISPR Journal` | Filter works published in specific journals, proceedings, or books. |
| `query_publisher` | string | No | `Wiley` | Search works issued by specific publishers. |
| `filter_type` | string | No | `journal-article` | Restrict results by Crossref publication type. |
| `filter_from_pub_date` | string | No | `2020-01-01` | Filter works published on or after date (YYYY, YYYY-MM, or YYYY-MM-DD). |
| `filter_until_pub_date` | string | No | `2026-12-31` | Filter works published on or before date. |
| `filter_has_license` | boolean | No | `true` | Restrict output to works carrying explicit license metadata. |
| `filter_has_abstract` | boolean | No | `true` | Filter for works with indexed abstract text. |
| `filter_has_funder` | boolean | No | `true` | Filter for works with registered funding agency metadata. |
| `filter_funder_id` | string | No | `10.13039/100000001` | Filter by Crossref Funder Registry DOI (e.g. NSF or NIH). |
| `filter_member` | string | No | `311` | Filter by Crossref publisher member ID. |
| `sort` | string | No | `relevance` | Sort field (`relevance`, `published`, `is-referenced-by-count`, `updated`, `created`). |
| `order` | string | No | `desc` | Ordering direction (`desc` or `asc`). |
| `mailto` | string | No | `reapxdev@proton.me` | Email address sent in API headers for Crossref Polite Pool access. |
| `max_results` | integer | Yes | `50` | Maximum number of work records to return (1 to 10,000). |

#### Worked Input Example

```json
{
  "query": "crispr",
  "query_container_title": "The CRISPR Journal",
  "filter_type": "journal-article",
  "filter_has_license": true,
  "sort": "published",
  "order": "desc",
  "mailto": "reapxdev@proton.me",
  "max_results": 50
}
```

***

### ⬆️ Output

All extracted work metadata items are written directly to the run's default dataset.

#### Output Fields

| Field | Type | Description | Example |
| :--- | :--- | :--- | :--- |
| `paperId` | string | Sanitized DOI with colons replaced by hyphens for entity page addressing. | `10.1089-crispr.2018.29011.rba` |
| `doi` | string | Raw canonical Digital Object Identifier. | `10.1089/crispr.2018.29011.rba` |
| `title` | string | Primary title of the paper, article, or chapter. | `Cultivating CRISPR` |
| `publicationYear` | integer | Four-digit publication year. | `2018` |
| `publicationDate` | string | Full ISO publication date or date string (YYYY-MM-DD or YYYY-MM). | `2018-04-19` |
| `type` | string | Crossref work type classification. | `journal-article` |
| `publisher` | string | Publishing house or issuing organization name. | `SAGE Publications` |
| `containerTitle` | string | Title of journal, book series, or conference volume. | `The CRISPR Journal` |
| `volume` | string | Journal volume designation. | `1` |
| `issue` | string | Journal issue designation. | `2` |
| `page` | string | Page range or article number. | `99-100` |
| `issn` | string | Comma-separated list of print and electronic ISSNs. | `2573-1599, 2573-1602` |
| `isbn` | string | Comma-separated list of ISBNs (for books/chapters). | `978-0-12-345678-9` |
| `authors` | string | Comma-separated author full names. | `Rodolphe Barrangou` |
| `authorCount` | integer | Total number of listed authors. | `1` |
| `firstAuthorAffiliation` | string | Institutional affiliation of the lead author. | `Editor-in-Chief, The CRISPR Journal` |
| `isReferencedByCount` | integer | Total citations reported in Crossref index. | `15` |
| `referenceCount` | integer | Total references in bibliography. | `0` |
| `isOpenAccess` | boolean | True if license or open access links are present. | `true` |
| `licenseUrl` | string | URL of reuse or text/data mining license. | `http://www.liebertpub.com/nv/resources-tools/` |
| `funderNames` | string | Comma-separated funding agency names. | `National Institutes of Health` |
| `funderIds` | string | Comma-separated funder registry DOIs. | `10.13039/100000002` |
| `url` | string | Canonical HTTP URL for resolving the DOI. | `https://doi.org/10.1089/crispr.2018.29011.rba` |
| `pdfUrl` | string | Direct URL to full text PDF document if available. | `https://journals.sagepub.com/doi/pdf/10.1089/crispr.2018.29011.rba` |
| `abstract` | string | Plain-text work abstract (HTML tags stripped). | `This paper reviews recent developments in CRISPR gene editing...` |
| `subject` | string | Subject categories or classifications. | `Genetics, Biotechnology` |
| `language` | string | Language code. | `en` |

#### Worked Output Example

```json
{
  "paperId": "10.1089-crispr.2018.29011.rba",
  "doi": "10.1089/crispr.2018.29011.rba",
  "title": "Cultivating CRISPR",
  "publicationYear": 2018,
  "publicationDate": "2018-04-19",
  "type": "journal-article",
  "publisher": "SAGE Publications",
  "containerTitle": "The CRISPR Journal",
  "volume": "1",
  "issue": "2",
  "page": "99-100",
  "issn": "2573-1599, 2573-1602",
  "isbn": null,
  "authors": "Rodolphe Barrangou",
  "authorCount": 1,
  "firstAuthorAffiliation": "Editor-in-Chief, The CRISPR Journal",
  "isReferencedByCount": 15,
  "referenceCount": 0,
  "isOpenAccess": true,
  "licenseUrl": "http://www.liebertpub.com/nv/resources-tools/text-and-data-mining-policy/121/",
  "funderNames": null,
  "funderIds": null,
  "url": "https://doi.org/10.1089/crispr.2018.29011.rba",
  "pdfUrl": "http://www.liebertpub.com/doi/pdf/10.1089/crispr.2018.29011.rba",
  "abstract": null,
  "subject": null,
  "language": "en"
}
```

***

### How it works

1. **Polite API Requests:** Uses plain HTTP requests sent to Crossref REST endpoints with user-agent identification for routing through Crossref's high-speed Polite Pool.
2. **Deep Cursor Pagination:** Automatically paginates through search results using Crossref's `cursor` mechanism to retrieve large datasets reliably without loss of state.
3. **Dual Identifier Generation:** Emits both `doi` (the raw DOI string) and `paperId` (with colons replaced by hyphens). This ensures 100% entity page addressability across all datasets regardless of colons in DOIs.
4. **Progressive Pushing:** Pushes items in small batches to the default dataset as soon as they are processed.
5. **Tiered Billing Safety:** Charges strictly per returned item written to dataset. If the run budget cap (`ACTOR_MAX_TOTAL_CHARGE_USD`) is reached, execution stops cleanly without dropping completed records.

***

### ❓ FAQ

##### How are DOIs formatted in the output?

Crossref DOIs are emitted in two fields:

- `doi`: The exact, raw DOI string as registered in Crossref (e.g. `10.1051/0004-6361:20010000`).
- `paperId`: The sanitized DOI with colons replaced by hyphens (e.g. `10.1051-0004-6361-20010000`). This ensures valid identifier matching for entity pages.

##### How much does a run cost?

This actor uses **Pay-Per-Event** pricing. You are charged $0.002 per record returned (with automatic plan discounts down to $0.0008 at higher subscription tiers). Unsuccessful queries or empty results cost $0.00.

##### Why set the `mailto` field?

Providing an email address in `mailto` (default: `reapxdev@proton.me`) identifies your requests to Crossref's API servers. Crossref uses this to route traffic to their dedicated Polite Pool, providing significantly faster response times and higher rate limits.

##### Can I extract direct PDF download links?

Yes. When publishers provide full text PDF links in Crossref metadata, they are extracted into the `pdfUrl` field.

***

### 💬 Your feedback

We continuously improve our scrapers based on user feedback. If you discover a bug, request a new metadata field, or need custom extraction rules:

- Contact maintainers directly: <reapxdev@proton.me>
- Visit our asset portal: <https://reapx.dev>

***

*Disclaimer: Unofficial - not affiliated with Crossref. 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": "climate change",
  "sort": "relevance",
  "max_results": 50,
  "mailto": "reapxdev@proton.me"
}
```

### 📄 Sample output

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

```json
{
  "paperId": "10.1055/s-0036-1589185",
  "doi": "10.1055/s-0036-1589185",
  "title": "Synthesis of Exochomine",
  "publicationYear": 2016,
  "publicationDate": "2016-09-19",
  "type": "journal-article",
  "publisher": "Georg Thieme Verlag KG",
  "containerTitle": "Synfacts",
  "volume": "12",
  "issue": "10",
  "page": "1002-1002",
  "issn": "1861-1958, 1861-194X",
  "isbn": null,
  "authors": null,
  "authorCount": 0,
  "firstAuthorAffiliation": null,
  "isReferencedByCount": 0,
  "referenceCount": 0,
  "isOpenAccess": true,
  "licenseUrl": null,
  "funderNames": null,
  "funderIds": null,
  "url": "https://doi.org/10.1055/s-0036-1589185",
  "pdfUrl": "http://www.thieme-connect.de/products/ejournals/pdf/10.1055/s-0036-1589185.pdf",
  "abstract": null,
  "subject": null,
  "language": "en"
}
```

### ⚠️ 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`):

Enter free-text keywords or phrase to search Crossref DOI metadata across titles, abstracts, and full texts (e.g. <code>climate change</code> or <code>crispr</code>). <br><br><b>Consequence:</b> Broader search terms match more records, extending run time and consuming more budget. <b>Empty value:</b> Leave empty to search without keyword constraints when filtering by author, publisher, or date.

## `query_author` (type: `string`):

Filter work records by author given name or family name (e.g. <code>Doudna</code> or <code>Vaswani</code>). <br><br><b>Consequence:</b> Restricts results strictly to works matching the specified author, reducing total records matched. <b>Empty value:</b> Leave empty to include works from all authors regardless of author name.

## `query_title` (type: `string`):

Search specifically within publication and work title fields (e.g. <code>deep learning</code>). <br><br><b>Consequence:</b> Limits matching works to those containing the specified terms in their title, increasing query precision. <b>Empty value:</b> Leave empty to search across all metadata fields.

## `query_container_title` (type: `string`):

Filter works published in specific journals, proceedings, or book series (e.g. <code>Nature</code> or <code>The CRISPR Journal</code>). <br><br><b>Consequence:</b> Restricts search results to specific publications, avoiding records from other journals. <b>Empty value:</b> Leave empty to query works across all journals and containers.

## `query_publisher` (type: `string`):

Search works issued by specific publishers (e.g. <code>Elsevier</code>, <code>Wiley</code>, or <code>Springer</code>). <br><br><b>Consequence:</b> Filters results to publications from matching publishing houses. <b>Empty value:</b> Leave empty to include publications from all registered Crossref member publishers.

## `filter_type` (type: `string`):

Filter by Crossref work category (e.g. <code>journal-article</code>, <code>book-chapter</code>, <code>proceedings-article</code>). <br><br><b>Consequence:</b> Narrows output to a specific work type, ignoring all other publication formats. <b>Empty value:</b> Leave empty to retrieve works of any publication type.

## `filter_from_pub_date` (type: `string`):

Start date for publication filtering formatted as YYYY, YYYY-MM, or YYYY-MM-DD (e.g. <code>2020-01-01</code>). <br><br><b>Consequence:</b> Excludes works published prior to this date threshold. <b>Empty value:</b> Leave empty to include older historical publications back to the start of the index.

## `filter_until_pub_date` (type: `string`):

End date for publication filtering formatted as YYYY, YYYY-MM, or YYYY-MM-DD (e.g. <code>2026-12-31</code>). <br><br><b>Consequence:</b> Excludes works published after this date threshold. <b>Empty value:</b> Leave empty to include recent publications up to the current date.

## `filter_has_license` (type: `boolean`):

Filter for works that include explicit licensing metadata or open reuse policies in Crossref. <br><br><b>Consequence:</b> Excludes records lacking registered license statements. <b>Empty value:</b> Leave false or empty to include works with or without explicit license metadata.

## `filter_has_abstract` (type: `boolean`):

Filter for works that contain indexed abstract text in Crossref metadata. <br><br><b>Consequence:</b> Filters out records that do not contain an abstract, returning higher-detail items. <b>Empty value:</b> Leave false or empty to include records regardless of abstract availability.

## `filter_has_funder` (type: `boolean`):

Filter for works that carry research funding agency metadata or grant IDs. <br><br><b>Consequence:</b> Narrows output to funded research publications. <b>Empty value:</b> Leave false or empty to include unfunded and funded publications alike.

## `filter_funder_id` (type: `string`):

Filter works funded by a specific agency using its Crossref Funder Registry DOI (e.g. <code>10.13039/100000001</code> for NSF). <br><br><b>Consequence:</b> Limits output to projects funded by that specific agency. <b>Empty value:</b> Leave empty to include works funded by any or no agency.

## `filter_member` (type: `string`):

Filter works by Crossref publisher member ID (e.g. <code>78</code> for Elsevier, <code>311</code> for Wiley, <code>179</code> for SAGE). <br><br><b>Consequence:</b> Restricts results to the specified publisher member. <b>Empty value:</b> Leave empty to search across all registered publishers.

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

Select field used to order returned work records (e.g. <code>relevance</code>, <code>published</code>, or <code>is-referenced-by-count</code>). <br><br><b>Consequence:</b> Determines which matching items sort first during partial extraction runs. <b>Empty value:</b> Defaults to relevance score ordering.

## `order` (type: `string`):

Order results in descending or ascending direction for the chosen sort field. <br><br><b>Consequence:</b> <code>desc</code> puts highest relevance or newest works first; <code>asc</code> reverses order. <b>Empty value:</b> Defaults to <code>desc</code>.

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

Email address sent in Crossref API headers to route requests to Crossref's high-speed Polite Pool (e.g. <code>reapxdev@proton.me</code>). <br><br><b>Consequence:</b> Provides higher rate limits and reliable response times. <b>Empty value:</b> Defaults to <code>reapxdev@proton.me</code>.<br><br>Leave this field empty to skip this filter.

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

Maximum number of work records to return and push to the default dataset (e.g. <code>50</code> or <code>1000</code>). <br><br><b>Consequence:</b> Higher values collect larger datasets but take longer and cost more per record event. <b>Empty value:</b> Defaults to 50 records.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## Actor input object example

```json
{
  "query": "10.1002",
  "sort": "relevance",
  "order": "desc",
  "mailto": "reapxdev@proton.me",
  "max_results": 50
}
```

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

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/crossref-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": "10.1002" }

# Run the Actor and wait for it to finish
run = client.actor("reapx/crossref-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": "10.1002"
}' |
apify call reapx/crossref-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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