Lead generation
EU CORDIS API — Horizon Europe & H2020 Scraper
EU CORDIS API scraper for Horizon Europe and Horizon 2020 grant projects. Exports funding amounts, coordinator, participants, programme, dates, and objectives as structured JSON. Four input modes, 20 fields per row.
Free Apify credit covers a first run. No credit card to try.
What this Actor scrapes
One ResultRow per project. Every row carries the same 20 columns regardless of which input mode you used. Data is published by the European Commission under CC-BY 4.0 (EU Open Data policy).
What we handle for you
- Four input modes in one Actor —
projectIds,searchQuery,programmeFilter,countryFilter. Pydantic XOR validator enforces exactly one mode before any network call. - Horizon Europe and Horizon 2020 both supported via the
frameworkswitch (HORIZON,H2020, orANY). - Coordinator-country filter implemented as a server-side scan with in-process post-filtering — CORDIS's search API does not expose coordinator country as a query field, so the Actor scans pages and emits only matching rows.
- Single-hit anomaly handled — CORDIS returns
hits.hitas a dict (not a list) when only one project matches; the parser's_ensure_list()normalises every nested array so the same code path handles both shapes. - Programme primary selection respects
@attributes.uniqueProgrammePart=true— multi-programme projects expose the correct top-level programme code, not the first nested one. - Optional full-abstract mode —
includeFullAbstract=truedeep-fetches the project detail HTML page via parsel and replaces the truncated search-API objective with the full text; charged asresult-row-detailed($0.005) instead ofresult-row($0.003). - Pydantic v2 input + output models —
ResultRow.statusis validated against the live enum (SIGNED,CLOSED,TERMINATED);country_filternormalised to upper-case at validation. - Browser fingerprint rotation —
curl-cffireplays real-browser TLS handshakes (Chrome 131 impersonation) so the target sees a genuine browser client, not Python. Profiles rotate across requests on any target that fingerprints clients. - Residential proxy rotation — Apify Proxy routes requests through fresh exit IPs on every block. A
4xxor5xxresponse invalidates the current session; we request a newsession_idand retry automatically. - Exponential backoff with
Retry-Afterhonoured —429and503responses trigger retries with 2 s base, doubling up to 30 s, max 5 attempts. We never hammer the endpoint; partial successes surface with a clear status message rather than silently returning an empty dataset. - Rate-limit pacing — page scanning for country-filter mode is paced so bursts don't trigger throttling mid-run.
- Clean typed rows — Pydantic-validated output, ISO-8601 timestamps, stable IDs. No raw dicts, no silent nulls.
- Pay only for results that land — PPE pricing means no charge for rows that never emit. Only the small
actor-startwarm-up fee applies if a run returns zero rows.
Use cases
- Grant writer competitive intelligence — pull all
HORIZON.2.5(Climate, Energy and Mobility) projects from the last 12 months to map who is winning which calls in your topic area. - Research-institution portfolio reporting — filter by
countryFilter=DE(or your country) to enumerate every Horizon Europe project coordinated nationally, with funding totals. - Science-policy analysis — bulk-export H2020 vs HORIZON funding distributions across funding schemes (RIA / IA / CSA / ERC) for a programme retrospective.
- EU innovation consulting — feed a list of
projectIds(e.g. from a client's reference list) and return clean structured records for proposal due diligence. - University tech-transfer offices — track CLOSED projects in their field where commercial follow-on opportunities (IP licensing, spinout candidates) may have emerged.
- Journalists & think-tanks — measure the country, programme, and consortium composition across an entire framework programme using the
horizon europe project datareturned per row. - B2B SaaS prospecting — use
coordinator_organization+coordinator_countryto build a list of EU research-project leaders as a prospecting signal for tools that sell into that audience.
Input
Paste this into the Apify Console, or send it as the run input over the API. Proxy settings are on by default; you rarely need to touch them.
| Field | Type | Required | What it does |
|---|---|---|---|
projectIds | array | no | Explicit CORDIS project IDs to fetch (e.g. 101069357). Exactly one of projectIds, searchQuery, programmeFilter, or countryFilter must be provided. |
searchQuery | string | no | Free-text query against the CORDIS search index (e.g. quantum computing or hydrogen storage). 1-500 chars. |
programmeFilter | string | no | Programme code, e.g. HORIZON.2.5 (Climate, Energy and Mobility) or H2020-EU.1.1. (ERC). |
countryFilter | string | no | ISO 3166-1 alpha-2 of the coordinator country (e.g. DE, ES, NL). Lower-case is normalised to upper. Implemented as a post-filter on search results — pagination may scan more API pages than maxProjects to collect that… |
framework | string | no | Restrict to one framework programme or search both. Ignored when projectIds mode is used. |
maxProjects | integer | no | Max ResultRows emitted in list modes (search, programme, country). Ignored when projectIds mode is used. |
includeFullAbstract | boolean | no | Deep-fetch the project detail HTML page to extract the untruncated objective text. Adds one extra request per row and switches PPE event from result-row ($0.003) to result-row-detailed ($0.005). |
useProxy | boolean | no | Route requests through Apify Proxy (BUYPROXIES94952). CORDIS does not currently rate-limit datacenter IPs; leave off unless you see 429. |
{
"searchQuery": "quantum computing",
"framework": "HORIZON",
"maxProjects": 100,
"includeFullAbstract": false,
"useProxy": false
} Output
One row per result, schema-validated before it is written. Export JSON, CSV, Excel or XML from the run, or read it over the API.
project_idproject_acronymproject_titleproject_urlprogrammeprogramme_display_namecall_idfunding_schemestart_dateend_datetotal_cost_eureu_contribution_eurstatuscoordinator_organizationcoordinator_countryparticipating_organizations
{
"project_id": "101069357",
"project_acronym": "Photo2Fuel",
"project_title": "Artificial PHOTOsynthesis to produce FUELs and chemicals",
"project_url": "https://cordis.europa.eu/project/id/101069357/en",
"programme": "HORIZON.2.5",
"programme_display_name": "Climate, Energy and Mobility",
"call_id": "HORIZON-CL5-2021-D2-01",
"funding_scheme": "HORIZON-RIA",
"start_date": "2022-09-01",
"end_date": "2025-08-31",
"total_cost_eur": 2493171.25,
"eu_contribution_eur": 2493171.0,
"status": "SIGNED",
"coordinator_organization": "IDENER RESEARCH & DEVELOPMENT AIE",
"coordinator_country": "ES",
"participating_organizations": [
"FUNDACION TECNALIA RESEARCH & INNOVATION",
"UPPSALA UNIVERSITET"
],
"participating_countries": [
"DE",
"ES",
"SE"
],
"objective_summary": "The Photo2Fuel project will develop a breakthrough technology that converts CO2 into useful fuels and chemicals...",
"keywords": [
"solar energy",
"bacteria",
"archaea",
"solar fuels",
"CO2 reduction"
],
"scraped_at": "2026-05-16T12:00:00.000000+00:00"
} Pricing
| Event | Price | When |
|---|---|---|
| Actor start | $0.20 | Once per run, covers warm-up and proxy session setup. |
| Result row emitted | $0.0030 | Per result written to the dataset. |
| Result row emitted (detailed) | $0.0050 | Per result written to the dataset. |
You pay only for results that land. Cap any run with maxTotalChargeUsd. See pricing & billing for worked examples.
Limitations
- HORIZON and H2020 only. FP7 and earlier framework programmes are not indexed in the current CORDIS search index; this Actor returns zero rows for FP6-and-earlier queries.
- No deliverables, publications, or result documents. Available on the project detail page but not in the search API; out of scope for this Actor.
- No organisation-level enrichment. Legal address, VAT ID, org type category — out of scope; use a dedicated organisation enrichment Actor.
- Country filter is post-filter, not server-side. CORDIS's search API does not expose coordinator country as a query field. Country-filter mode scans pages and keeps only rows where
coordinator_countrymatches. To collectmaxProjects=500German projects, the Actor may scan 1,500+ projects total. The emitted row count is always≤ maxProjects. - Status filter is not a user input. The search API's status field path does not reliably filter server-side — status is emitted on every output row so you can filter the dataset client-side after the run.
- Page size is fixed at 50. CORDIS's
num=100parameter returns only 10 results (verified 2026-05-16) — the Actor usesnum=50everywhere as the effective practical maximum. - 7-day default storage retention on the Apify FREE tier. Export your dataset immediately after the run or upgrade for longer retention.
- CORDIS data is CC-BY 4.0. Attribution to the European Commission's CORDIS service is required when republishing.
FAQ
What is the EU CORDIS API and what does this Actor do with it?
https://cordis.europa.eu/search/en?format=json. This Actor wraps that endpoint with four input modes (project ID lookup, free-text search, programme filter, coordinator-country filter), handles pagination, normalises the raw API response into clean typed rows, and streams results into an Apify dataset in JSON, CSV, Excel, or XML. No registration or API key is required.Does this cover Horizon Europe and Horizon 2020?
framework input field (HORIZON, H2020, or ANY). The CORDIS search index covers Horizon Europe (2021–2027) and H2020 (2014–2020). FP7 and earlier frameworks are not indexed and will return zero results.Why is the `objective_summary` cut off?
includeFullAbstract=true to make the Actor follow up with a per-project GET to the detail page (/project/id/{id}/en) and extract the untruncated objective via a CSS selector. This switches the PPE event from result-row ($0.003) to result-row-detailed ($0.005) per row.Why is country-filter mode slow for large result sets?
coordinator/country=DE returns zero results (verified 2026-05-16). We implement country filtering by scanning all-framework results and retaining only matching rows. To collect maxProjects=500 German-coordinated projects, the Actor may scan 1,500+ projects. The emitted dataset row count is always ≤ maxProjects.Can I filter by project status (SIGNED / CLOSED / TERMINATED)?
What about `horizon europe grants scraper` alternatives?
Are CORDIS results free to redistribute?
How much horizon europe project data can I pull per run?
maxProjects input caps runs at 1–5,000 rows. For programme-filter and search-query modes, results are paginated at 50 per page — a 5,000-row run makes ~100 API pages. Country-filter mode may scan significantly more pages to collect matching rows (see the Limitations section above).Ready to run it?
Open the listing on Apify, paste the input above, and watch rows land. If it ever breaks, it is our problem before it is yours.
Related Actors