You find the perfect paper for your research. You click the link. And you hit a $40 paywall.
But what if that same paper is legally available for free somewhere else?
Unpaywall checks 50,000+ open-access sources to find free legal copies of paywalled papers. It covers 30M+ articles. And it has a free API.
How It Works
Give Unpaywall a DOI, and it tells you:
- Is there a free legal version?
- Where is it hosted? (university repo, preprint server, author page)
- What type of open access? (gold, green, hybrid, bronze)
Quick Start
import requests
def find_free_version(doi, email):
resp = requests.get(f"https://api.unpaywall.org/v2/{doi}", params={"email": email})
data = resp.json()
if data.get("is_oa"):
best = data.get("best_oa_location", {})
print(f"FREE version found!")
print(f" URL: {best.get('url_for_pdf') or best.get('url')}")
print(f" Host: {best.get('host_type')} ({best.get('repository_institution', 'N/A')})")
print(f" OA type: {data.get('oa_status')}")
else:
print(f"No free version found for {doi}")
# Example: famous AlphaFold paper
find_free_version("10.1038/s41586-021-03819-2", "your@email.com")
Output:
FREE version found!
URL: https://europepmc.org/articles/pmc8371605?pdf=render
Host: repository (Europe PMC)
OA type: green
Batch Check Multiple Papers
dois = [
"10.1038/s41586-021-03819-2", # AlphaFold
"10.1126/science.abj8754", # Some Nature paper
"10.1016/j.cell.2021.12.006", # Cell paper
"10.1145/3442188.3445922", # ACM paper
]
for doi in dois:
resp = requests.get(f"https://api.unpaywall.org/v2/{doi}",
params={"email": "your@email.com"})
data = resp.json()
title = data.get("title", "Unknown")[:50]
status = "FREE" if data.get("is_oa") else "PAYWALLED"
oa_type = data.get("oa_status", "closed")
print(f"[{status:>9}] ({oa_type:>7}) {title}")
Build a Paywall Bypass Checker
def check_reading_list(dois, email):
results = {"free": [], "paywalled": []}
for doi in dois:
resp = requests.get(f"https://api.unpaywall.org/v2/{doi}",
params={"email": email})
data = resp.json()
title = data.get("title", doi)
if data.get("is_oa"):
best = data.get("best_oa_location", {})
url = best.get("url_for_pdf") or best.get("url", "")
results["free"].append({"title": title, "url": url})
else:
results["paywalled"].append({"title": title, "doi": doi})
print(f"\nResults: {len(results['free'])} free, {len(results['paywalled'])} paywalled")
print(f"\nFree papers:")
for p in results["free"]:
print(f" {p['title'][:60]}")
print(f" {p['url']}")
return results
Combine with Crossref for Full Pipeline
def search_and_find_free(query, email, top=5):
# Step 1: Search Crossref for papers
resp = requests.get("https://api.crossref.org/works", params={
"query": query, "rows": top, "sort": "is-referenced-by-count", "order": "desc"
})
papers = resp.json()["message"]["items"]
# Step 2: Check each for free version
for paper in papers:
doi = paper.get("DOI")
title = paper.get("title", ["N/A"])[0][:50]
cites = paper.get("is-referenced-by-count", 0)
oa = requests.get(f"https://api.unpaywall.org/v2/{doi}",
params={"email": email}).json()
free = "FREE" if oa.get("is_oa") else "PAID"
print(f"[{free}] {title} ({cites:,} cites)")
search_and_find_free("deep learning medical imaging", "your@email.com")
API Details
-
Endpoint:
https://api.unpaywall.org/v2/{doi}?email=you@email.com - Rate limit: 100K requests/day
- Auth: Just your email address (no key)
- Coverage: 30M+ articles checked against 50K+ sources
- Data dump: Full dataset available for download
Pro Tips
- Always prefer
url_for_pdfoverurlwhen available - Check
oa_locationsarray for ALL free versions, not just the best one - Green OA = author/repository copy, Gold = publisher open access
- Combine with Crossref to search by topic, then check OA status
- The browser extension is great for manual checking
Unpaywall + Crossref + OpenAlex = the ultimate free research stack.
Do you hit paywalls often? What is your workflow for finding free papers? Share in the comments.
More research API tools on GitHub.\n\n---\n\n## More Free Research APIs\n\nThis is part of my series on free APIs for researchers and data scientists:\n\n- OpenAlex API — 250M+ Academic Works\n- CORE API — 260M+ Scientific Papers\n- Crossref API — DOI Metadata for 150M+ Papers\n- Unpaywall API — Find Free Paper Versions\n- Europe PMC — 40M+ Biomedical Papers\n- World Bank API — GDP & Economic Data\n- ORCID API — 18M+ Researcher Profiles\n- DBLP API — 6M+ CS Publications\n- NASA APIs — 20+ Free Space Data APIs\n- FRED API — 800K+ US Economic Time Series\n- All 30+ Research APIs Mapped\n\n*Tools: Academic Research Toolkit on GitHub*
Top comments (0)