# Academic Paper Resolver — DOI/arXiv to Citations for AI (`haketa/academic-resolver`) Actor

Resolve any DOI, arXiv, PubMed ID or paper title into rich metadata: authors, abstract, venue, citation count, references, open-access PDF and cross-IDs. Merged from multiple scholarly sources into RAG-ready Markdown for AI agents & research tools.

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

## Pricing

from $1.40 / 1,000 results

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

## Academic Paper Resolver — DOI, arXiv & PubMed to Metadata & Citations

Turn any **DOI, arXiv ID, PubMed ID, or paper title** into a rich, structured record: **authors, abstract, venue, year, citation count, references, open-access PDF, topics and cross-IDs** — merged from several scholarly databases into one clean answer, plus a **RAG-ready Markdown card**.

Built for **AI agents, research assistants, literature reviews and RAG pipelines**. No API key, no setup.

***

### Why this Actor?

An LLM can't reliably recall a paper's exact citation count, its DOI, or who it cites — that data lives across OpenAlex, Crossref, arXiv and PubMed, each with a different format and different gaps. This Actor is the **scholarly grounding** an agent needs: give it an identifier (or a title) and get back verified metadata it can cite, with a PDF link when the paper is open access.

- **RAG & literature review** — resolve a batch of DOIs, embed the abstracts and reference lists, and ground your assistant in real papers.
- **AI research agents** — a tool an agent calls to answer "what is this paper, how many times is it cited, and what does it reference?"
- **Citation graphs** — walk references (and, optionally, citing papers) to map a research area.
- **Reference management & enrichment** — clean up a messy bibliography into structured, deduplicated records.

Because it merges multiple sources, a gap in one is filled by another: OpenAlex provides the backbone and topics, Crossref adds a titled reference list, arXiv supplies the abstract and PDF for preprints.

***

### What you get

For every query, one structured record:

| Field | Description |
| --- | --- |
| `query` | What you asked for |
| `resolved` | Whether a paper was found |
| `title` | Paper title |
| `authors` | Author list |
| `year` | Publication year |
| `venue` | Journal / conference / source |
| `publisher` | Publisher |
| `doi`, `arxivId`, `pmid`, `openAlexId` | Cross-identifiers |
| `citationCount` | Times cited |
| `referenceCount` | Number of references |
| `influentialCitationCount` | Influential citations (when available) |
| `isOpenAccess`, `oaStatus` | Open-access status |
| `pdfUrl` | Open-access PDF link (when available) |
| `abstract` | Abstract |
| `concepts` | Topics / fields |
| `tldr` | One-line summary (when available) |
| `references` | Full reference list (titles, years, DOIs) |
| `citations` | Papers that cite this one (optional) |
| `markdown` | A **RAG-ready paper card** |
| `url` | Landing page |
| `sources` | Which databases contributed |
| `scrapedAt` | Timestamp |

***

### Example output

```json
{
  "query": "10.1038/nature14539",
  "resolved": "true",
  "title": "Deep learning",
  "authors": "Yann LeCun, Yoshua Bengio, Geoffrey E. Hinton",
  "year": "2015",
  "venue": "Nature",
  "doi": "10.1038/nature14539",
  "pmid": "26017442",
  "citationCount": "81929",
  "referenceCount": "50",
  "isOpenAccess": "true",
  "pdfUrl": "https://hal.science/hal-04206682",
  "concepts": "Computer science, Deep learning, Artificial intelligence",
  "sources": "OpenAlex, Crossref",
  "markdown": "# Deep learning\n\n**Yann LeCun, Yoshua Bengio, Geoffrey E. Hinton · 2015 · Nature**\n\nCited by 81929 · ...",
  "scrapedAt": "2026-07-06T15:00:00.000Z"
}
```

The `markdown` field renders as a self-contained card:

> # Attention Is All You Need
>
> **Ashish Vaswani, Noam Shazeer, … · 2017 · arXiv**
> Cited by 100000+ · Open access
> [PDF](https://arxiv.org/pdf/1706.03762)
>
> ## Abstract
>
> The dominant sequence transduction models are based on complex recurrent or convolutional neural networks …

***

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `queries` | array | — | **Required.** DOIs, arXiv IDs, PubMed IDs, or titles — mixed is fine. |
| `includeReferences` | boolean | `true` | Include the paper's reference list. |
| `includeCitations` | boolean | `false` | Also fetch papers that cite this one (extra lookup). |
| `maxReferences` | integer | `50` | Cap references / citations per paper. |

#### The Actor auto-detects each identifier

- **DOI** — `10.1038/nature14539` or a `https://doi.org/…` URL
- **arXiv** — `1706.03762`, `arXiv:1706.03762`, or old-style `hep-th/9901001`
- **PubMed** — a bare PMID like `26017442`
- **Title** — any free text, resolved by best match

#### Example input

```json
{
  "queries": [
    "10.1038/nature14539",
    "1706.03762",
    "26017442",
    "attention is all you need"
  ],
  "includeReferences": true
}
```

***

### Use cases in detail

#### 1. RAG & literature review

Feed a list of DOIs, take the `abstract` and `markdown` fields, embed them, and your assistant now answers from real papers — with citation counts and DOIs for provenance. The `references` array gives you the next hop for expanding a review.

#### 2. AI research agents

Expose this as a tool so an agent can resolve a paper mid-task: "summarize this DOI and tell me how influential it is." The agent gets structured, sourced data instead of guessing.

#### 3. Citation-graph exploration

Turn on `includeCitations` to fetch papers that cite a work, and use `references` for papers it cites — build a two-way citation graph around a seed paper.

#### 4. Bibliography cleanup & enrichment

Have a messy list of titles or half-formed references? Resolve them into clean records with DOIs, years and venues, deduplicated by identifier.

#### 5. Open-access discovery

`isOpenAccess` and `pdfUrl` tell you instantly whether a paper is freely readable and where to get the PDF.

***

### How to use it

1. Click **Try for free**.
2. Paste identifiers or titles into `queries`.
3. Click **Start**.
4. Read the results as **JSON, CSV, Excel**, or via the Apify API.

Batches resolve in parallel — a hundred papers finish in well under a minute.

***

### Calling from the API

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "queries": ["10.1038/nature14539", "1706.03762"] }'
```

Then fetch the dataset:

```bash
curl "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs/last/dataset/items?token=YOUR_APIFY_TOKEN"
```

Works with webhooks, Zapier, Make and n8n.

***

### Frequently asked questions

**What can I search by?**
DOI, arXiv ID, PubMed ID, or a plain title — mixed in one run. Each is auto-detected.

**Where does the data come from?**
Multiple open scholarly databases are merged so gaps in one are covered by another. The `sources` field lists which contributed to each record.

**Why is an abstract sometimes missing?**
Some publishers (e.g. certain Nature titles) don't release abstracts to any open database. When that happens the field is empty even though the rest of the metadata is complete.

**Do I get the full reference list?**
When the publisher deposits references (most do), yes — titled and dated. `referenceCount` always reflects the total.

**Can I get citing papers too?**
Yes — set `includeCitations: true`.

**Is it good for RAG?**
Yes — use the `markdown` card or the `abstract` for embeddings, and keep `doi`/`url` for citations.

**Can an AI agent call this automatically?**
Yes — it's keyless and returns structured JSON, ideal as an agent/MCP tool.

***

### Tips for great results

- **Prefer identifiers over titles.** A DOI or arXiv ID resolves the exact paper; a title returns the best match, which may differ for very common titles.
- **Batch your DOIs.** Resolving 100 at once is far faster than one at a time.
- **Chunk by reference.** The `references` array is a natural boundary for building citation-aware embeddings.
- **Keep the DOI.** Store it with each embedding so your assistant can cite its source.

***

### Notes

This Actor retrieves bibliographic metadata from open scholarly sources for research, indexing and AI-grounding purposes. Metadata may be incomplete or contain source-side errors; verify against the publisher of record for critical use. Abstracts and content remain the rights of their respective publishers and authors.

*Metadata aggregated from open scholarly databases including OpenAlex, Crossref and arXiv.*

***

### Support

Want another identifier type, more citation depth, or an extra field? Open an issue from the Actor's page. Happy researching.

# Actor input Schema

## `queries` (type: `array`):

Paste anything that identifies a paper — DOIs, arXiv IDs, PubMed IDs, or plain paper titles. Mixed lists are fine. Leave empty to run a ready-made sample of landmark papers.

## `includeReferences` (type: `boolean`):

Add the paper's reference list (the works it cites) to each result.

## `includeCitations` (type: `boolean`):

Also fetch newer papers that cite this one (adds one extra lookup per paper).

## `maxReferences` (type: `integer`):

Cap how many references and citing papers are returned for each paper. Use 0 for no limit.

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

Safety cap on the total number of papers resolved in one run. Use 0 for no limit. Applied to your list and to the built-in sample.

## `proxyConfiguration` (type: `object`):

Apify Proxy settings. The scholarly sources are public, so a proxy is OFF by default.

## Actor input object example

```json
{
  "queries": [
    "10.1038/nature14539",
    "1706.03762",
    "attention is all you need"
  ],
  "includeReferences": true,
  "includeCitations": false,
  "maxReferences": 50,
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

What you asked for

## `resolved` (type: `string`):

Whether a paper was found

## `title` (type: `string`):

Paper title

## `authors` (type: `string`):

Authors

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

Publication year

## `venue` (type: `string`):

Journal / venue

## `doi` (type: `string`):

DOI

## `arxivId` (type: `string`):

arXiv ID

## `pmid` (type: `string`):

PubMed ID

## `citationCount` (type: `string`):

Times cited

## `referenceCount` (type: `string`):

Number of references

## `isOpenAccess` (type: `string`):

Open access

## `pdfUrl` (type: `string`):

Open-access PDF URL

## `abstract` (type: `string`):

Abstract

## `concepts` (type: `string`):

Topics / concepts

## `url` (type: `string`):

Landing page

## `markdown` (type: `string`):

RAG-ready paper card

## `scrapedAt` (type: `string`):

Timestamp

# 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 = {
    "queries": [
        "10.1038/nature14539",
        "1706.03762",
        "attention is all you need"
    ],
    "maxReferences": 50,
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/academic-resolver").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 = {
    "queries": [
        "10.1038/nature14539",
        "1706.03762",
        "attention is all you need",
    ],
    "maxReferences": 50,
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/academic-resolver").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 '{
  "queries": [
    "10.1038/nature14539",
    "1706.03762",
    "attention is all you need"
  ],
  "maxReferences": 50,
  "maxResults": 100
}' |
apify call haketa/academic-resolver --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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