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

# Load OpenAIRE research products for a search into pandas and Parquet

Source entry: https://signal-lab-jet.vercel.app/datasets/openaire-graph-api
Provider: https://graph.openaire.eu/docs/apis/graph-api/
Checked against the provider's documentation: 2026-11-03

## Access
- No key for up to 60 requests an hour; register for a personal access token (valid for one hour at a time) for up to 7,200 an hour.
- Base URL https://api.openaire.eu/graph/; research products are at v1/researchProducts with search, type, date and paging parameters.

## Request
```bash
curl 'https://api.openaire.eu/graph/v1/researchProducts?search=sovereign%20debt&type=publication&fromPublicationDate=2025-01-01&pageSize=100&page=1'
```

## Format
JSON with header (numFound, page, pageSize, nextCursor) and results; each research product has id, mainTitle, publicationDate, type, bestAccessRight, pids (scheme and value, such as doi), authors and descriptions.

## Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
```python
"""OpenAIRE Graph research products -> pandas -> Parquet. Unauthenticated: up to 60 requests an hour."""
import requests
import pandas as pd

params = {"search": "sovereign debt", "type": "publication", "pageSize": 100, "page": 1,
          "fromPublicationDate": "2025-01-01"}
r = requests.get("https://api.openaire.eu/graph/v1/researchProducts", params=params, timeout=90)
r.raise_for_status()
js = r.json()
rows = [{
    "openaire_id": p.get("id"),
    "title": p.get("mainTitle"),
    "publication_date": p.get("publicationDate"),
    "type": p.get("type"),
    "best_access_right": (p.get("bestAccessRight") or {}).get("label"),
    "doi": next((pid.get("value") for pid in (p.get("pids") or []) if pid.get("scheme") == "doi"), None),
} for p in js["results"]]
df = pd.DataFrame(rows)
df.to_parquet("openaire_products.parquet", index=False)
print(len(df), "research products on this page of", js["header"]["numFound"], "matches")
```
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 research products on this page of 1556 matches

## Limits
- 60 requests per hour without a token; up to 7,200 per hour with one.
- Offset paging stops at 10,000 results per query; use cursor paging or the bulk graph download for more.

## Quirks
- Records are deduplicated across sources, so ids can look like doi_dedup___::... rather than a DOI.
- bestAccessRight can be missing; treat it as unknown, not closed.

## Terms and attribution
- Records may be reused commercially and non-commercially under CC BY, with OpenAIRE acknowledged as the data source.
- Terms page: https://graph.openaire.eu/docs/apis/terms

## Sources
- https://graph.openaire.eu/docs/apis/terms: "The rate limit for the former type of requests is up to 7200 requests per hour, while the latter is up to 60 requests per hour."
- https://graph.openaire.eu/docs/apis/terms: "OpenAIRE Graph license is CC-BY: the records returned by the service can be freely re-used by commercial and non-commercial partners under CC-BY license, hence as long as OpenAIRE is acknowledged as a data source."
- https://graph.openaire.eu/docs/apis/graph-api/: "limits offset-based paging to 10,000 results per query."

## 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.
