OpenAlex Scraper: Works, Authors & Institutions
Pricing
from $0.37 / 1,000 entity scrapeds
OpenAlex Scraper: Works, Authors & Institutions
Scrape the OpenAlex scholarly graph: works with authors, institutions, topics, citation counts, open-access status and funding. Free, unauthenticated, no proxy.
Pricing
from $0.37 / 1,000 entity scrapeds
Rating
0.0
(0)
Developer
Arman Hossain
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share

Exports the open scholarly graph: 320M+ works with their authors, institutions, topics, citation counts, open-access status and funding, plus the author, institution, source, funder and publisher records those works link to.
OpenAlex is the open replacement for Microsoft Academic Graph. This Actor reads it directly, so there's no browser, no proxy and no authentication. Paging is handled for you, including past the offset ceiling that would otherwise cap a large result set.
Agent skill: SKILL.md
https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/openalex-scraper.md
What you get
Every record carries the same key set regardless of entity type, so a mixed dataset still loads into one table. Fields that do not apply are null.
| Field | What it holds |
|---|---|
entityType, openalexId, shortId, url | Which collection the record came from, its full OpenAlex URI and the bare ID (W2101234009) |
displayName, title | Entity name, and for works the paper title |
doi, landingPageUrl | DOI and publisher landing page |
publicationYear, publicationDate, type, language, isRetracted | Work metadata |
openAccessStatus, isOpenAccess, oaUrl | OA colour (gold, green, bronze, hybrid, closed), flag, and free full-text URL |
sourceName, sourceType, sourceIssn, hostOrganization | The journal, repository or conference the work appeared in |
authorships, authorCount | Author name, ORCID, position, corresponding flag, affiliations and countries. Capped at the first 100 authors |
institutions | Distinct affiliated institutions across all authors |
concepts, topics | Legacy concepts with scores, plus the current topic, field and domain taxonomy |
citedByCount, worksCount, referencedWorksCount | Citation and output counts |
fundingGrants | Funder name, funder ID and grant number per award |
orcid, ror, countryCode, homepageUrl | Identifiers for author, institution and source records |
hIndex, i10Index, twoYearMeanCitedness | OpenAlex summary statistics |
lastKnownInstitutions | Current affiliations on author records |
searchQuery, updatedDate, scrapedAt | Which query produced the record, when OpenAlex last touched it, and when this run read it |
RUN_SUMMARY in the key-value store holds per-run counts, the filters you used, and the outcome of every query: the ones that failed, the ones that matched nothing, and the ones skipped because the run's cap was already spent.
Use cases
- Institutional output. Filter on a ROR ID and count works per year and topic.
- Collaborator discovery. Pull works on a topic, then group by author and affiliation.
- Open-access tracking. Count
openAccessStatusby publisher, funder or year. - Systematic reviews. Run several search strings, dedupe on
doi, and export to CSV for screening. - RAG and knowledge bases. Clean DOI-keyed metadata that joins to Crossref, PubMed and ORCID.
Quick start
One search, default cap:
{"entityType": "works","searchQueries": ["large language models"]}
Recent open-access articles across two topics, tagged per query:
{"entityType": "works","searchQueries": ["crispr gene editing", "base editing"],"filters": {"publication_year": ">2022","is_oa": "true","type": "article"},"mailto": "you@example.com","maxResults": 1000}
Everything one institution published last year, no free-text search at all:
{"entityType": "works","filters": {"authorships.institutions.ror": "https://ror.org/042nb2s44","publication_year": "2025"},"mailto": "you@example.com","maxResults": 5000}
Input
| Field | Type | Default | Notes |
|---|---|---|---|
entityType | string | works | works, authors, institutions, sources, concepts, topics, funders or publishers. |
searchQueries | array | [] | One pass per query, results tagged with the query. Empty means a single unfiltered sweep. The same query written twice is run once. |
filters | object | {} | Key/value OpenAlex filter expressions, joined into one filter= parameter. |
mailto | string | "" | Contact email sent with each request, identifying you as the operator. Worth setting on large runs. |
maxResults | integer | 200 | The most records the whole run may return, across every query. Must be 1 or more — there is no unlimited value. |
The Actor runs green with no input at all: it returns the first 200 works OpenAlex serves.
maxResults is the run total and the number you are billed against, never a per-query allowance. Three queries at maxResults: 300 return 300 records, not 900: the budget is split evenly across the queries and recomputed from what has actually been delivered, so a query that runs out early leaves its share to the ones after it. If the budget is spent before the last query is reached, those queries are named in RUN_SUMMARY.targetsSkipped rather than dropped silently. A record already returned by an earlier query is not returned — or charged — a second time; the count is in RUN_SUMMARY.duplicatesSkipped.
Filter values pass through untouched, so OpenAlex operators work: ">2020", "!null", "2020-2024". Array values are joined with |, which OpenAlex reads as OR, so {"type": ["article", "preprint"]} becomes type:article|preprint. An unknown filter key returns HTTP 400 and OpenAlex lists every valid field in the error, which the Actor copies into RUN_SUMMARY.failures.
Output example
{"entityType": "works","openalexId": "https://openalex.org/W4404534210","shortId": "W4404534210","displayName": "A Survey on Hallucination in Large Language Models: Principles, Taxonomy, Challenges, and Open Questions","title": "A Survey on Hallucination in Large Language Models: Principles, Taxonomy, Challenges, and Open Questions","doi": "https://doi.org/10.1145/3703155","publicationYear": 2024,"publicationDate": "2024-11-20","type": "article","language": "en","isRetracted": false,"openAccessStatus": "bronze","isOpenAccess": true,"oaUrl": "https://dl.acm.org/doi/pdf/10.1145/3703155","landingPageUrl": "https://doi.org/10.1145/3703155","sourceName": "ACM Transactions on Information Systems","sourceType": "journal","sourceIssn": "1046-8188","hostOrganization": null,"authorships": [{"name": "Weijiang Yu","authorId": "A5055989750","orcid": "https://orcid.org/0000-0002-7449-3093","position": "middle","isCorresponding": false,"institutions": ["Huawei Technologies (China)"],"countries": ["CN"]}],"authorCount": 11,"institutions": ["Harbin Institute of Technology", "Huawei Technologies (China)"],"concepts": [{ "name": "Visual Hallucination", "level": 2, "score": 0.564 }],"topics": [{ "name": "Topic Modeling", "field": "Computer Science", "domain": "Physical Sciences", "score": 0.9926 }],"citedByCount": 1757,"referencedWorksCount": 214,"fundingGrants": [],"updatedDate": "2026-08-05T07:39:15.569665","url": "https://openalex.org/W4404534210","searchQuery": "large language models","scrapedAt": "2026-08-06T11:43:13.229Z"}
An authors record fills a different subset: worksCount, hIndex, i10Index, twoYearMeanCitedness, lastKnownInstitutions, and a topics list where each entry carries a works count rather than a relevance score.
Writing filters
Filters are where the real power is. A few that come up constantly:
| Goal | Filter |
|---|---|
| Works from one institution | {"authorships.institutions.ror": "https://ror.org/042nb2s44"} |
| Works by one author | {"author.orcid": "https://orcid.org/0000-0002-7449-3093"} |
| Published since 2022 | {"publication_year": ">2021"} |
| Journal articles only | {"type": "article"} |
| Open access only | {"is_oa": "true"} |
| In one journal | {"primary_location.source.issn": "1046-8188"} |
| Highly cited | {"cited_by_count": ">100"} |
| Funded by NSF | {"awards.funder_id": "F4320306076"} |
To find an institution's ROR or a funder's OpenAlex ID, run the Actor once with entityType: "institutions" or "funders" and a search query. The ror and shortId fields it returns are exactly what the filters above expect.
API example
curl -X POST "https://api.apify.com/v2/acts/arman-bd~openalex-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"entityType": "works","searchQueries": ["retrieval augmented generation"],"filters": { "publication_year": ">2023", "is_oa": "true" },"mailto": "you@example.com","maxResults": 500}'
JavaScript example
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('arman-bd/openalex-scraper').call({entityType: 'works',filters: { 'authorships.institutions.ror': 'https://ror.org/042nb2s44', publication_year: '2025' },mailto: 'you@example.com',maxResults: 2000,});const { items } = await client.dataset(run.defaultDatasetId).listItems();const oaShare = items.filter((w) => w.isOpenAccess).length / items.length;console.log(`${items.length} works, ${(oaShare * 100).toFixed(1)}% open access`);
Notes
- Paging is always cursor-based. Every query starts at
cursor=*and followsmeta.next_cursor. Offset paging silently caps at 10,000 records and cursor paging does not, somaxResultsis the only limit that applies. - Each request returns 200 records, which is OpenAlex's maximum. A 5,000-record query is 25 requests.
- Setting
mailtois worth it on large runs. Your address is sent with each request and carried in the User-Agent, which is what the OpenAlex docs ask of automated clients. - Author lists are capped at 100. Some consortium papers list thousands of authors, and
authorCountalways reports the true total. - One bad query won't kill the run. A 400 or 404 is recorded in
RUN_SUMMARY.failuresand the remaining queries continue, delivering their records as normal. The Actor throws only when every query failed and nothing was returned. - A query that matched nothing is named too, in
RUN_SUMMARY.emptyQueries, with its match count inRUN_SUMMARY.queries[]. Zero rows from a query you ran and zero rows from a query that was never reached look identical in a dataset; the summary is what tells them apart. - The cap is checked before anything is fetched.
maxResultsbelow 1, fractional or unreadable stops the run immediately with an error naming the field, rather than being read as "no limit" — nothing is fetched and nothing is charged. - Transient errors get retried. A throttled or 5xx response is retried up to three times with growing backoff, honouring the wait the response asks for up to a 30-second ceiling, and each request has a 60-second timeout because a full 200-record page can take ten seconds or more. A request the source rejects outright, and a payload that is not the expected shape, are final for that query and are recorded rather than retried.
FAQ
Do I need an API key? No. You supply no credentials.
Do I need a proxy? No. Proxy configuration is not required to run this Actor.
How many records can one run return? Exactly as many as you set maxResults to, across all queries together — that is the number you are billed against. Cursor paging has no ceiling, so multi-hundred-thousand-record exports are a matter of run time and the cap you set, not API limits.
Can I get abstracts? OpenAlex ships abstracts as an inverted index rather than text, and licensing varies by source, so this Actor does not emit them. Use oaUrl or landingPageUrl to fetch the full text where it is openly available.
Concepts or topics? Topics are the current taxonomy (topic, then subfield, field and domain) and are what OpenAlex maintains. Concepts are the legacy Microsoft Academic Graph vocabulary, kept for continuity. Both are returned for works.
Can I schedule it? Yes. Diff on openalexId plus updatedDate to pick up only records OpenAlex has revised since the last run.