By the fastCRW team · Catalogue figures checked 2026-11-05 against GET /v1/data · Verify independently before relying on any figure.
The OpenAlex API lets you search more than 300 million scholarly works, authors, institutions and topics with plain HTTP calls. This guide shows how to run those searches from Python and from an agent, using the OpenAlex provider in the Pergamon catalogue, so one fastCRW key also covers the Crossref DOI metadata at the end.
What OpenAlex covers
The OpenAlex introduction page describes "the curated core corpus of 300M+ works" and says "all data is CC0". The entities you will query most are works (papers, books, datasets), authors, institutions, sources (journals and venues), topics and funders. Pergamon exposes each one as its own capability under the openalex provider, so you pick the entity with the capability name.
The same introduction page says basic use is free and that a free API key raises your daily budget tenfold. Pergamon makes the call for you, and the upstream limits are OpenAlex's. Check their docs for current limits before you plan a large batch.
Search works
The works capability takes a search term and a select list. select returns only the fields you name, which keeps the response small. Run this call with your key:
curl "https://api.fastcrw.com/v1/data/openalex/works?search=retrieval%20augmented%20generation&select=id,title,publication_year" \
-H "Authorization: Bearer $CRW_API_KEY"
The call costs 1 credit. The response carries 25 results per page under data.results. Trimmed to the first two, the output looks like this:
{
"results": [
{"id": "https://openalex.org/W4410705984", "title": "Corrective Retrieval Augmented Generation", "publication_year": 2025},
{"id": "https://openalex.org/W4389519118", "title": "Active Retrieval Augmented Generation", "publication_year": 2023}
]
}
Use filter when you need exact conditions instead of a text match. A filter takes OpenAlex's own filter syntax, and the next section shows the most useful one: filtering by an entity ID.
Two steps: resolve an entity, then filter works by its ID
Names are ambiguous, so resolve a name to an OpenAlex ID first. The autocomplete capability returns candidates with an id and a filter_key that tells you which filter to use. Here is the first step for an author:
curl "https://api.fastcrw.com/v1/data/openalex/autocomplete?entity_type=authors&q=yoshua%20bengio" \
-H "Authorization: Bearer $CRW_API_KEY"
Trimmed to the first candidate, the response contains:
{
"results": [
{
"id": "https://openalex.org/A5086198262",
"display_name": "Yoshua Bengio",
"hint": "Canadian Institute for Advanced Research, Canada",
"entity_type": "author",
"filter_key": "authorships.author.id"
}
]
}
The second step puts the ID into a filter on works. Keep the short form of the ID (A5086198262) in the filter value:
curl "https://api.fastcrw.com/v1/data/openalex/works?filter=authorships.author.id:A5086198262&select=id,title,publication_year" \
-H "Authorization: Bearer $CRW_API_KEY"
The first three titles returned for that author were "Deep learning" (2015), "Gradient-based learning applied to document recognition" (1998) and "Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation" (2014). Pick the candidate whose hint matches your institution before you trust the list, because two people can share a name.
Find the papers that cite a work
For citations, filter works with cites and the ID of the cited work. This call lists works that cite "Corrective Retrieval Augmented Generation" (W4410705984, the first hit from the search above):
curl "https://api.fastcrw.com/v1/data/openalex/works?filter=cites:W4410705984&select=id,title,publication_year" \
-H "Authorization: Bearer $CRW_API_KEY"
The response has the same shape as a search: 25 results under data.results, and the total in data.meta.count. Page through it with page or cursor.
Python with the SDK
The Python SDK sends the same calls and returns the upstream body with its provenance. Install it with pip install crw, and it reads CRW_API_KEY from the environment:
# pip install crw
from crw import CrwClient
client = CrwClient() # reads CRW_API_KEY
result = client.get_data("openalex", "works", {"search": "retrieval augmented generation", "select": "id,title,publication_year"})
print(result["provenance"]["attributionText"])
for work in result["data"]["results"][:5]:
print(work["publication_year"], work["title"])
The SDK returns camelCase keys such as creditsUsed and attributionText. The REST response uses snake_case keys such as credits_used. Use whichever surface you call, and do not mix them in one script.
When a call fails, the SDK raises CrwApiError with an error_code attribute. Catch that error in a loop and branch on the code, so an invalid_options error stops the script while an upstream error can be retried later.
Add Crossref metadata for a DOI
When you already hold a DOI, Crossref is the first place to check. The agency capability on the crossref provider tells you which registration agency holds a DOI. For the Nature paper with DOI 10.1038/nature14539 the call is:
curl "https://api.fastcrw.com/v1/data/crossref/agency?doi=10.1038/nature14539" \
-H "Authorization: Bearer $CRW_API_KEY"
The response message is {"DOI": "10.1038/nature14539", "agency": {"id": "crossref", "label": "Crossref"}}. Use the agency result to route a DOI to the right metadata source before you fetch its record. Crossref's own licence statement says almost none of its metadata is subject to copyright, and the provenance block on each response carries that licence line.
From an agent
An MCP client calls the same capability with a tool call. The hosted endpoint at https://fastcrw.com/mcp exposes two data tools, crw_find_data for discovery and crw_get_data for calls. This is the tools/call payload for the search above:
{"name": "crw_get_data", "arguments": {"provider": "openalex", "capability": "works", "options": {"search": "retrieval augmented generation", "select": "id,title,publication_year"}}}
MCP results are capped at 256 KiB. A large unfiltered works response can hit that cap and be refused with result_too_large, and the refused call is refunded for server sources. The select option is the simplest way to keep each result small, so use it on every agent call.
Paging and page size
Use page or cursor to move through results. The works capability returns 25 results per page, and it does not accept a per_page option. Sending one returns an error with errorCode invalid_options and the list of valid options, so plan your loop around 25 results per call. This is the error a works call returns when it includes per_page:
{
"success": false,
"error": "openalex/works has no option \"per_page\". Its options are: search, filter, sort, page, cursor, select, group_by, sample, seed.",
"errorCode": "invalid_options"
}
The error names the valid options, so an agent can correct its own call on the next turn.
Calls that OpenAlex refuses or times out return success: false and are not billed. Retry after a short wait rather than in a tight loop.
A literature scan in four steps
A typical scan for a research agent combines the calls above in a fixed order:
- Search
workswithsearchand a narrowselectto build a candidate list. - Resolve any author or institution the question names with
autocomplete, and check thehintbefore you use the ID. - Re-run
workswith afilteron that ID to see the author's other papers. - For each DOI you plan to cite, call
crossrefagencyto confirm which registry holds it.
With select on the work calls, each step returns only the fields the next step needs, so the chain stays readable in the model's context.
Pick the capability for the question
Each OpenAlex entity has its own capability, and the option names differ between them. This table maps the common questions to the capability and the option to start with:
| Question | Capability | Start with |
|---|---|---|
| Papers about a topic | works | search or filter |
| Who is this researcher? | autocomplete | entity_type and q |
| Everything by one author | works | filter with authorships.author.id |
| Papers that cite a work | works | filter with cites |
| Journals and venues | sources | search |
| Research topics | topics | search |
| Funders of research | funders | search |
| Registration agency for a DOI | crossref agency | doi |
The works capability also accepts sort, cursor, group_by, sample and seed. These options are passed through to OpenAlex, which defines what each one does. Run GET /v1/data/find?provider=openalex to see the options a capability accepts before you write a loop, because an option the capability does not know is refused, not ignored.
Use the results in a retrieval pipeline
A retrieval-augmented agent needs an identifier it can cite and a title it can show. The works in the examples above carry both, so the agent can list candidates first and read further only for the ones it will rely on. Keep the OpenAlex ID as the citation key.
Store the provenance with the results, not beside them. Each response names OpenAlex as the source and carries the attribution text "Source: OpenAlex". If a model later quotes a work, your system can attach that text to the answer without a second lookup.
What this does not do
- It does not return full text. OpenAlex returns metadata and its own abstract fields, and you should read the original publisher for the full article.
- It does not lift OpenAlex's own limits. A large batch can see refused calls (an upstream 429), and a refused call is not billed, so back off and retry.
- It does not guarantee coverage of a given paper. OpenAlex decides what is in its index, and the catalogue passes that through.
- It does not replace a citation database for a formal bibliometric study. Check the method against the OpenAlex docs before you publish a number from it.
Sources
- OpenAlex API reference: introduction
- OpenAlex FAQ: how OpenAlex is licensed
- Crossref REST API documentation
- OpenAlex on Pergamon and Crossref on Pergamon
Related: Public data API for AI agents · Deep research agent with fastCRW · Pergamon catalogue
