# Crossref DOI Metadata Search & Enrichment (`technicaldost/crossref-doi-metadata`) Actor

Resolve Crossref DOIs or search scholarly works. Export titles, journals, publication dates, citation counts and deposited license links. No abstracts, authors or contacts.

- **URL**: https://apify.com/technicaldost/crossref-doi-metadata.md
- **Developed by:** [Technical Dost Solutions](https://apify.com/technicaldost) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 successful records

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

## Crossref DOI Metadata Search & Enrichment

Resolve a list of Crossref DOIs or search scholarly works by topic. Get flat publication metadata ready for CSV, JSON, spreadsheets and reference-enrichment pipelines. No API key or login required.

The Actor uses Crossref's documented public REST API. It does not fetch publisher websites, PDFs, article bodies, abstracts, author profiles or contact information. Person-level fields and abstracts are never written to its dataset. Lookup responses are normalized in memory and discarded; search requests select only the output metadata fields.

### Pricing

$1 per 1,000 successfully resolved records. $0.001 per run. Standard-run platform usage is included. Only successful eligible rows in the default dataset trigger the result charge. Error, not-found, skipped and robots-denied diagnostics do not trigger a result charge. The run fee, where listed, still applies to empty or failed runs. Memory is limited to 256–512 MB. Set a maximum run cost in Apify; inspect the actual dataset and run charge breakdown after an interruption. Input item limits bound work and do not replace the run spending limit.

### What you get

- DOI and resolver link, title, publication type, publisher and journal/container title.
- Publication date with its original precision: year, month or day.
- Crossref-reported reference and citation counts, with missing values kept null.
- Deposited license URLs and update relations as evidence, not unsupported legal or research-integrity conclusions.
- Source endpoint and retrieval timestamp on every row.
- A separate SUMMARY record describing limits, unavailable data and unknown DOIs.

### Quick start

Look up a DOI:

```json
{"mode":"lookup","dois":["10.1038/nphys1170"],"maxItems":10}
```

Search a topic:

```json
{"mode":"search","query":"solar cell efficiency","fromDate":"2024-01-01","workType":"journal-article","sort":"published","maxItems":100}
```

In Apify, open the dataset to export JSON, CSV or Excel. The output tab links to both the dataset and SUMMARY.

### Input

| Field | Default | Meaning |
|---|---|---|
| mode | lookup | lookup or search |
| dois | none | 1–100 Crossref DOIs or doi.org URLs; lookup only |
| query | none | Required keyword phrase in search mode, maximum 300 characters |
| maxItems | 100 | Global unique-output cap, 1–1,000 |
| pageSize | 100 | Search rows per request, 1–1,000; constant during pagination, initially capped at maxItems |
| maxPages | 20 | Search page cap, 1–50 |
| fromDate / toDate | none | Search publication-date bounds in YYYY-MM-DD |
| workType | all | Optional supported Crossref publication type |
| sort | relevance | relevance, published, is-referenced-by-count or updated; descending |

Search and lookup fields cannot be combined. Exact duplicate DOIs are normalized and requested once per run. No email is transmitted to Crossref and the Actor uses the public pool. A descriptive User-Agent identifies the software and its public developer page. All requests are sequential with at least 1.1 seconds between starts. This meets the July 2026 public-list limit of one request per second; stricter response headers and Retry-After delays are respected.

### Output semantics

Each dataset row represents one unique DOI. See dataset-item.schema.json for the full contract.

- publicationDate can be `2020`, `2020-02`, `2020-02-29` or null. datePrecision tells you which.
- citedByCount is Crossref's count, not a complete citation census or an impact factor. Missing is null; a reported zero stays zero.
- licenses are deposited links, not a verified determination that a publication is open access or that reuse is lawful. Content version and start date matter.
- updates contains Crossref's update-to relationships. An empty list does not prove a work has never been corrected or retracted. No boolean safety/retraction certificate is inferred.
- sourceUrl identifies the official record API. doiUrl points to the DOI resolver and is never automatically fetched.

SUMMARY status can be complete, no_matches, limited, partial or error. `notFound` lists requested DOIs absent from Crossref. A 404 is not proof that the DOI is invalid: another registration agency may manage it. An all-error run fails after writing SUMMARY, instead of silently succeeding with an empty dataset.

Search uses documented offset pagination within the first 10,000 source positions. Rows stay constant during a run, while dataset output is trimmed to maxItems. It stops on a short page, maximum items, maximum pages, no new DOIs, or the source-position bound. Duplicate/non-progress pages and malformed rows are disclosed. An output cap is not a claim of exhaustive retrieval. Pagination is not a frozen snapshot; the upstream index can change, causing omissions or duplicates. DOI deduplication removes repeats but cannot recover omitted records. The Actor does not offer bulk corpus harvesting or cursor pagination.

### Limits and responsible use

- Crossref metadata coverage depends on deposits and updates. Missing or outdated records are possible.
- No full text, abstracts, emails, author names, ORCID profiles, institution contacts, paywall access or non-Crossref enrichment.
- No browser, residential proxy, rotating IP, CAPTCHA handling or access-control bypass. HTTP 403 stops further requests in the run. Transient errors receive at most three attempts; an exhausted rate limit or source failure stops subsequent DOI requests too.
- Responses are capped at 5 MB and requests at 30 seconds. A long Retry-After interval stops the request with a clear rerun-later status rather than retrying early.
- Do not enter sensitive or secret information in queries. Queries and DOIs go to Crossref. The platform also stores the task input and summary in the operator's account.
- This is independent software, not affiliated with or endorsed by Crossref.

### License and source documentation

[Crossref's metadata licensing statement](https://www.crossref.org/documentation/retrieve-metadata/#licensing) says bibliographic facts can be reused without restriction and Crossref-generated data is CC0. Abstracts retain publisher or author copyright, so this Actor excludes them. A publication's deposited content license is separate from the metadata license.

- [Official REST API](https://www.crossref.org/documentation/retrieve-metadata/rest-api/)
- [Access and authentication](https://www.crossref.org/documentation/retrieve-metadata/rest-api/access-and-authentication)
- [July 2026 rate-limit update](https://community.crossref.org/t/refining-rest-api-limits-for-improved-stability-and-reliability/16137)
- [Official offset pagination and parameter documentation](https://github.com/CrossRef/rest-api-doc#offset)
- [August 2026 cursor restrictions](https://community.crossref.org/t/changes-to-cursors-filtering-and-sorting-in-the-rest-api/16246)

# Actor input Schema

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

Look up provided Crossref DOIs or search by keyword.

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

Up to 100 DOIs, DOI: values or doi.org URLs. Use only in lookup mode.

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

Required in search mode. Search public scholarly titles/topics. Do not send secrets or personal data.

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

Hard cap on unique records returned in this run.

## `pageSize` (type: `integer`):

Constant rows per search request, capped initially at maxItems. Output is trimmed to the unique-record limit.

## `maxPages` (type: `integer`):

Second safety bound. Searches also stop before passing 10,000 source positions.

## `fromDate` (type: `string`):

Optional real YYYY-MM-DD date, search only.

## `toDate` (type: `string`):

Optional real YYYY-MM-DD date, search only.

## `workType` (type: `string`):

Search filter only.

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

Descending order. Citation counts cover Crossref, not all citations.

## Actor input object example

```json
{
  "mode": "lookup",
  "dois": [
    "10.1038/nphys1170"
  ],
  "maxItems": 1,
  "pageSize": 1,
  "maxPages": 1,
  "workType": "all",
  "sort": "relevance"
}
```

# Actor output Schema

## `metadata` (type: `string`):

No description

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

No description

# 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": "lookup",
    "dois": [
        "10.1038/nphys1170"
    ],
    "maxItems": 1,
    "pageSize": 1,
    "maxPages": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("technicaldost/crossref-doi-metadata").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": "lookup",
    "dois": ["10.1038/nphys1170"],
    "maxItems": 1,
    "pageSize": 1,
    "maxPages": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("technicaldost/crossref-doi-metadata").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": "lookup",
  "dois": [
    "10.1038/nphys1170"
  ],
  "maxItems": 1,
  "pageSize": 1,
  "maxPages": 1
}' |
apify call technicaldost/crossref-doi-metadata --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,technicaldost/crossref-doi-metadata"
        }
    }
}
```

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/4D6PhgPQDM1f95BfT/builds/r2Od030UcySlWirdE/openapi.json
