---
name: openalex-api-ingestion
description: "How to get OpenAlex API data into a pandas DataFrame and Parquet: access, the request, the format, limits, quirks and terms."
---

# Load OpenAlex works for a search into pandas and Parquet

Source entry: https://signal-lab-jet.vercel.app/datasets/openalex-api
Provider: https://help.openalex.org/api/
Checked against the provider's documentation: 2026-11-03

## Access
- No key for basic queries; set OPENALEX_API_KEY to send a free key (it raises the daily budget 10x and is needed for cursor paging past the first page).
- Base URL https://api.openalex.org; every entity type is an endpoint such as /works, /authors or /sources.

## Request
```bash
curl 'https://api.openalex.org/works?search=central%20bank%20digital%20currency&filter=publication_year:2025,is_oa:true&per_page=100'
```

## Format
JSON envelope with meta (count, page, per_page, cost_usd), results (entity objects) and group_by. Works carry id, doi, display_name, publication_year, cited_by_count, open_access and primary_location; nested entities come back as trimmed stubs.

## Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
```python
"""OpenAlex works -> pandas -> Parquet. No key needed for basic use; a free key (OPENALEX_API_KEY) raises the daily budget."""
import os
import requests
import pandas as pd

params = {
    "search": "central bank digital currency",
    "filter": "publication_year:2025,is_oa:true",
    "per_page": 100,
    "select": "id,doi,display_name,publication_year,cited_by_count,open_access,primary_location",
}
if os.environ.get("OPENALEX_API_KEY"):
    params["api_key"] = os.environ["OPENALEX_API_KEY"]
r = requests.get("https://api.openalex.org/works", params=params, timeout=60)
r.raise_for_status()
data = r.json()
rows = [{
    "openalex_id": w["id"],
    "doi": w.get("doi"),
    "title": w.get("display_name"),
    "year": w.get("publication_year"),
    "cited_by": w.get("cited_by_count"),
    "oa_status": (w.get("open_access") or {}).get("oa_status"),
    "landing_page": ((w.get("primary_location") or {}).get("landing_page_url")),
} for w in data["results"]]
df = pd.DataFrame(rows)
df.to_parquet("openalex_works.parquet", index=False)
print(len(df), "works on this page of", data["meta"]["count"], "matches; cost_usd per call:", data["meta"].get("cost_usd"))
```
Run by us on 2026-11-03 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 100 works on this page of 13312 matches; cost_usd per call: 0.001

## Limits
- No key: 10 requests per second; free key: 30 per second and $1 of usage a day, reset at midnight UTC.
- per_page is at most 100; basic paging stops at 10,000 results, beyond that use cursor paging with a free key.

## Quirks
- Filter by IDs (OpenAlex ID, DOI, ORCID, ROR, ISSN), not names: names are ambiguous.
- The default corpus is the curated core; corpus=all adds roughly 60% more works, mostly datasets and repository records.
- Titles, abstracts and affiliation strings are passed through unsanitized; escape them before display.

## Terms and attribution
- OpenAlex releases every record under CC0, with no personal-use-only carve-out.
- The API's since-a-date sync filters and the daily snapshot are paid services; the quarterly snapshot is free.
- Terms page: https://help.openalex.org/hc/en-us/articles/24397762024087-Pricing

## Sources
- https://help.openalex.org/api/: "Basic use is free. A free API key raises your daily budget 10×, and heavier use is pay-as-you-go."
- https://help.openalex.org/api/authentication: "To retrieve more than 10,000 results, use cursor paging (with a free key: without one, only the first page works)."
- https://help.openalex.org/hc/en-us/articles/24397762024087-Pricing: "Every account gets $1 of API usage per day for free, and if you need more than that, there are two ways to get it: pay as you go, or an annual plan."

## Help improve this skill
Missing a source, or see something to improve? Call the MCP tool suggest_source or feedback (or POST /api/suggest or /api/feedback). Reviewed ideas: https://signal-lab-jet.vercel.app/agent-suggestions

Information for educational purposes only. Free tiers, limits and licenses belong to the providers and may change; check the provider's own terms before using the data.
