# arXiv API — Paper Search, Abstracts, Authors & PDF Links (`highbrow_fame/arxiv-api`) Actor

Search arXiv by keyword, author, category or date, or fetch papers by id: title, authors, abstract, categories, DOI, versions, PDF/HTML links and optional full text. Unofficial arXiv API.

- **URL**: https://apify.com/highbrow_fame/arxiv-api.md
- **Developed by:** [yestrue](https://apify.com/highbrow_fame) (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

$0.30 / 1,000 papers

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

## arXiv API — Paper Search, Abstracts, Authors & PDF Links

Every paper arXiv lists for a search — or every id you give it — as one clean JSON record: arXiv id and version, title, authors with affiliations, abstract, all categories and the primary one, submission and update dates, DOI, journal reference, the authors' comment, and direct PDF, abstract-page and HTML links. Search by keywords, phrase, title, author or abstract, restrict to categories and a submission-date window, sort by relevance or date, and page through up to 1,000 results per query. Switch **Include full text** on and the Actor also reads the paper's arXiv HTML version and adds its running text as plain text — ready for an LLM, a literature review or a search index. Built on arXiv's public, key-less export API, at the pace arXiv asks for.

**Try it in 1 minute:**

1. Press **Start** — the prefilled input searches arXiv for *large language models agents* and returns the 25 most relevant papers.
2. About a minute later (arXiv asks for one request every 3 seconds, and pages hold 100 papers) the **Output** tab shows the records: title, authors, abstract, categories, dates, DOI and PDF link, each with its position and the total number of matches.
3. Download JSON, CSV or Excel, or paste **Paper ids** or arxiv.org links, add **Categories** (`cs.CL`, `stat.ML`), a **Submitted from / to** window, change the sort, raise **Max results per query** to 1,000, or switch **Include full text** on.

Price: **$0.30 per 1,000 papers** (one paper = one record, with its full text included when you ask for it). Queries without matches, ids arXiv does not know and invalid inputs are free.

**Use it to:**

- Feed an AI agent or RAG pipeline with fresh papers: title, abstract and — for papers since December 2023 — the full text, without parsing PDFs.
- Watch a field on a schedule: everything submitted to `cs.CL` or `q-bio.NC` this week, newest first, straight into a sheet, a database or a Slack digest.
- Build a literature review: search several phrases, dedupe across them, and keep DOIs, journal references and PDF links for citation.
- Enrich a list of arXiv ids or links from a bibliography, a spreadsheet or a Zotero export with structured metadata.
- Track an author or a lab: `au:hinton`, `au:"Le Cun"`, sorted by last update, with every version's date.

### How it works

1. **Paper ids** are parsed from every form arXiv uses — `2303.08774`, `2303.08774v2`, `hep-th/9901001`, `arXiv:…`, `arxiv.org/abs|pdf|html/…` links and `10.48550/arXiv.…` DOIs — deduplicated, and fetched 100 per request with the export API's `id_list`. Results are matched to your inputs **by id**, never by position: an id arXiv does not know gets its own free `NOT_FOUND` record.
2. **Search queries** become arXiv `search_query` expressions. Plain words are searched in every field and ANDed (`all:large AND all:language …`); a quoted phrase stays a phrase. Lines that already use arXiv's prefixes (`ti:`, `au:`, `abs:`, `cat:`, `co:`, `jr:`, `rn:`, `id:`, `all:`) or `AND` / `OR` / `ANDNOT` go through untouched. **Categories** are appended as `AND (cat:cs.CL OR cat:cs.AI)`, the dates as `AND submittedDate:[…]`. Results come in pages of 100 up to **Max results per query**, sorted as you chose, each with its `position` and arXiv's `totalResults`.
3. The Atom feed arXiv returns is parsed into records: id and version split (`arxivId`, `version`, `arxivIdWithVersion`), whitespace in titles and abstracts collapsed, authors with `arxiv:affiliation`, `arxiv:doi`, `arxiv:journal_ref`, `arxiv:comment`, `arxiv:primary_category`, and the PDF link (always https). A paper that appears under several queries (or under an id and a query) is delivered once, under the first input that produced it.
4. **Include full text** fetches `https://arxiv.org/html/<id>v<n>` — arXiv's LaTeXML rendering, which exists for most papers submitted since December 2023 — and extracts the running text: title, abstract, sections and appendices, figure and table captions, table cells, math as its LaTeX source; footnotes, the reference list, the author block and page chrome are left out. The text is capped at **Max text length** (100,000 characters by default). A paper without an HTML version gets `fullText: null` and `fullTextError: "no HTML version"`. PDFs are deliberately not downloaded or parsed here — for PDF text use a PDF-to-text Actor on the `pdfUrl`.

**Politeness, by design:** arXiv asks API clients to make no more than one request every three seconds. This Actor runs every request — pages, id batches, HTML pages, retries — through one sequential queue with a 3-second gap, so there is no concurrency setting and a run of 1,000 papers with full text takes about an hour. An HTTP 429 or 503 from arXiv is waited out and retried on the same route. Requests go directly to arXiv; the proxy is used only to retry after a network error. E-mail addresses and phone numbers are removed from abstracts, comments and full text; author names and affiliations are kept — they are the public publication metadata arXiv shows.

### Input

| Field | What it does |
|---|---|
| `queries` | Searches, one per line: plain words, a `"quoted phrase"`, or arXiv syntax (`ti:`, `au:`, `abs:`, `cat:`, `AND`, `OR`, `ANDNOT`). |
| `ids` | Papers by id or link, one per line: `2303.08774`, `2303.08774v2`, `hep-th/9901001`, `arxiv.org/abs/…`, `arxiv.org/pdf/….pdf`, `10.48550/arXiv.…`. |
| `categories` | Restrict every search to these categories (ORed): `cs.CL`, `cs.AI`, `stat.ML`, `hep-th` … Without a query, the categories alone are searched. |
| `from`, `to` | Submission-date window, `YYYY-MM-DD`, applied to every search (not to ids). |
| `maxResults` | Papers per query, 1-1,000 (default 25); pages of 100. |
| `sortBy` | `relevance` (default), `lastUpdatedDate` or `submittedDate`, newest first. |
| `includeFullText` | Add the running text of the arXiv HTML version (default off; one extra request per paper). |
| `maxTextLength` | Characters of full text to keep (default 100,000). |
| `proxyConfiguration` | Used only to retry after a network error; the first try is direct. |

### Output

One record per paper:

| Field | What it is |
|---|---|
| `arxivId`, `version`, `arxivIdWithVersion` | `2303.08774`, `6`, `2303.08774v6` |
| `title`, `abstract`, `comment` | Plain text, whitespace collapsed (contacts removed from abstract and comment) |
| `authors[]` | `{ name, affiliation }` in arXiv order |
| `categories[]`, `primaryCategory` | All categories and the primary one |
| `publishedAt`, `updatedAt` | First submission and this version's date, ISO 8601 |
| `doi`, `journalRef` | Registered DOI and journal reference, when the authors gave them |
| `pdfUrl`, `absUrl`, `htmlUrl` | Links to this version's PDF, abstract page and HTML version (the HTML one may answer 404 for older papers) |
| `source`, `query`, `position`, `totalResults` | `search` or `id`; the query sent to arXiv; 1-based position in the results; arXiv's total count |
| `fullText`, `fullTextError` | Running text of the HTML version with Include full text on; why there is none, or that it was cut |
| `input`, `status`, `error`, `scrapedAt` | What you gave, `OK` / `NO_RESULTS` / `NOT_FOUND` / `INVALID_INPUT` / `FAILED`, the reason, and when |

#### Example

```json
{
  "input": "https://arxiv.org/abs/hep-th/9901001",
  "source": "id",
  "query": null,
  "arxivId": "hep-th/9901001",
  "version": 3,
  "arxivIdWithVersion": "hep-th/9901001v3",
  "title": "String Junctions and Their Duals in Heterotic String Theory",
  "authors": [{ "name": "Yosuke Imamura", "affiliation": null }],
  "abstract": "We explicitly give the correspondence between spectra of heterotic string theory and string junctions in type IIB theory.",
  "categories": ["hep-th"],
  "primaryCategory": "hep-th",
  "publishedAt": "1999-01-01T01:01:10.000Z",
  "updatedAt": "1999-05-10T04:45:54.000Z",
  "doi": "10.1143/PTP.101.1155",
  "journalRef": "Prog.Theor.Phys.101:1155-1164,1999",
  "comment": "13 pages + 4 eps figures, PTPTeX, typographical errors corrected",
  "pdfUrl": "https://arxiv.org/pdf/hep-th/9901001v3",
  "absUrl": "https://arxiv.org/abs/hep-th/9901001v3",
  "htmlUrl": "https://arxiv.org/html/hep-th/9901001v3",
  "position": null,
  "totalResults": null,
  "fullText": null,
  "fullTextError": "no HTML version",
  "status": "OK",
  "error": null,
  "scrapedAt": "2026-10-19T12:00:00.000Z"
}
```

### FAQ

**Is this an official API?** No, it's an unofficial API built on public pages and endpoints — arXiv's public export API (`export.arxiv.org/api/query`) and its HTML paper pages, which need no key. The data is what arXiv itself publishes; this Actor shapes it into stable JSON records, adds paging, id matching, deduplication and full text, and keeps to arXiv's request rate.

**Why is a run slow?** arXiv's terms ask clients for one request every three seconds, and this Actor follows that rule rather than hammering a free service: a page of 100 papers is one request, each paper's full text is one more. 25 papers with metadata take seconds; 1,000 papers with full text take about an hour. Run several Actors in parallel if you need more throughput — each keeps its own pace.

**Which papers have full text?** arXiv renders an HTML version for most papers submitted since December 2023 (and some earlier ones) whose LaTeX converts cleanly. For the rest `fullText` is null and `fullTextError` says `no HTML version`; the `pdfUrl` is always there, and a PDF-to-text Actor can read it.

**How do I search a title, an author or an abstract only?** Use arXiv's prefixes in the query line: `ti:"graph neural networks"`, `au:vaswani`, `abs:diffusion AND cat:cs.CV`. Lines with a prefix or a boolean operator are sent as written; plain lines are searched in all fields.

**Why did a search return fewer papers than `maxResults`?** arXiv had fewer matches (`totalResults` tells you how many), or some of the papers had already been delivered under an earlier query or id in the same run — each paper is delivered once.

**Like it?** A short review on the Store page helps other people find this Actor. Something missing or broken? Tell us on the Issues tab — we read every one.

### Related Actors

- [PDF to Markdown API](https://apify.com/highbrow_fame/pdf-to-markdown-api) — headings, tables and text of a PDF
- [PDF Text Extractor](https://apify.com/highbrow_fame/pdf-text-extractor) — text, pages and metadata from any PDF link
- [Hacker News Scraper](https://apify.com/highbrow_fame/hacker-news-stories) — stories, comments and search
- [Article Extractor API](https://apify.com/highbrow_fame/article-extractor-api) — title, author, date and full text of any article
- [Google News API](https://apify.com/highbrow_fame/google-news-api) — headlines by keyword and topic

# Actor input Schema

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

One search per line. Plain words are matched in every field (title, abstract, authors…); put a phrase in quotes. arXiv's own syntax goes through as is: ti:transformer, au:hinton, abs:"graph neural", cat:cs.CL, and AND / OR / ANDNOT between terms.

## `ids` (type: `array`):

Papers to fetch by id, one per line: 2303.08774, 2303.08774v2, hep-th/9901001, arXiv:2303.08774, an arxiv.org/abs, /pdf or /html link, or the 10.48550/arXiv.… DOI. Matched by id; an id arXiv does not know is a free NOT_FOUND record.

## `categories` (type: `array`):

arXiv categories to restrict every search to, one per line: cs.CL, cs.AI, cs.LG, stat.ML, hep-th, math.CO, q-bio.NC … Several are ORed. With no query, the categories alone are the search (latest papers in cs.CL).

## `from` (type: `string`):

Only papers first submitted on or after this day (YYYY-MM-DD). Applies to every search; ids are not filtered.

## `to` (type: `string`):

Only papers first submitted on or before this day (YYYY-MM-DD).

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

Papers per search query, up to 1,000 (read in pages of 100, one request every 3 seconds).

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

Relevance (arXiv's ranking), last updated date or first submitted date — newest first.

## `includeFullText` (type: `boolean`):

Read the paper's arXiv HTML version (arxiv.org/html/<id>, available for most papers since December 2023) and add its running text as plain text. One extra request per paper; a paper without an HTML version gets fullText null and fullTextError "no HTML version". PDFs are not read.

## `maxTextLength` (type: `integer`):

Characters of full text to keep per paper (the rest is cut; fullTextError says so).

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

Used only to try again after a network error: arXiv's API answers directly, so the first try of every request goes out without a proxy. Requests are sequential by design (arXiv asks for 3 seconds between them), so there is no concurrency setting.

## Actor input object example

```json
{
  "queries": [
    "large language models agents"
  ],
  "ids": [],
  "categories": [],
  "maxResults": 25,
  "sortBy": "relevance",
  "includeFullText": false,
  "maxTextLength": 100000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Every result as a JSON record, with a status for each input.

## `resultsCsv` (type: `string`):

The same records as CSV, for a spreadsheet.

# 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": [
        "large language models agents"
    ],
    "ids": [],
    "categories": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("highbrow_fame/arxiv-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 = {
    "queries": ["large language models agents"],
    "ids": [],
    "categories": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("highbrow_fame/arxiv-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 '{
  "queries": [
    "large language models agents"
  ],
  "ids": [],
  "categories": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call highbrow_fame/arxiv-api --silent --output-dataset

```

## MCP server setup

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