# EU CORDIS Grants Scraper (`devilscrapes/eu-cordis-grants`) Actor

Scrape EU CORDIS — the European Commission's R\&D project database. Get grants, participants, funding amounts, topics, and project IDs as typed dataset rows. We handle pagination, retries, and rate-limit pacing across CORDIS's federated endpoints.

- **URL**: https://apify.com/devilscrapes/eu-cordis-grants.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

<img src=".actor/icon.svg" width="160" alt="EU CORDIS Grants Scraper" />

## EU CORDIS Grants Scraper

_We do the dirty work so your dataset stays clean._ 😈

**$3.05 / 1,000 rows** — Export structured EU grant project records from the CORDIS database covering Horizon Europe (HORIZON) and Horizon 2020 (H2020) frameworks. Four input modes: direct project-ID lookup, free-text search, programme-code filter, and coordinator-country filter. Every row carries funding amounts, coordinator, participants, programme hierarchy, dates, status, and the project objective. Public CORDIS search API, no API key, no login, no browser automation.

CORDIS (Community Research and Development Information Service) is the EU's primary source for results of EU-funded research projects since FP1. The Horizon Europe (2021-2027, ~95 billion EUR budget) and Horizon 2020 (2014-2020, ~80 billion EUR closed) frameworks together expose 57,000+ project records. This Actor turns the awkward CORDIS web search into a clean JSON dataset for grant writers, research institutions, science-policy analysts, and EU innovation consultants. The only existing Apify Actor for CORDIS is marked DEPRECATED — there is zero active competition on the Store.

### 🎯 What this 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).

| Field | Type | Description |
|---|---|---|
| `project_id` | string | CORDIS numeric project ID |
| `project_acronym` | string \| null | Short acronym (e.g. `Photo2Fuel`) |
| `project_title` | string | Full project title |
| `project_url` | string | Public CORDIS project page URL |
| `programme` | string \| null | Primary programme code (e.g. `HORIZON.2.5`) |
| `programme_display_name` | string \| null | Programme title (e.g. `Climate, Energy and Mobility`) |
| `call_id` | string \| null | Master call identifier (e.g. `HORIZON-CL5-2021-D2-01`) |
| `funding_scheme` | string \| null | Funding scheme code (e.g. `HORIZON-RIA`, `ERC-COG`) |
| `start_date` | string \| null | Project start date (YYYY-MM-DD) |
| `end_date` | string \| null | Project end date (YYYY-MM-DD) |
| `total_cost_eur` | number \| null | Total project cost in EUR |
| `eu_contribution_eur` | number \| null | EU contribution (grant amount) in EUR |
| `status` | string \| null | `SIGNED`, `CLOSED`, or `TERMINATED` |
| `coordinator_organization` | string \| null | Legal name of the coordinator organisation |
| `coordinator_country` | string \| null | Coordinator country (ISO 3166-1 alpha-2) |
| `participating_organizations` | string[] | Legal names of all participating organisations |
| `participating_countries` | string[] | Deduped ISO 3166-1 alpha-2 codes of participants |
| `objective_summary` | string \| null | Project objective text (truncated unless `includeFullAbstract=true`) |
| `keywords` | string[] | Project keywords parsed from the comma-separated CORDIS string |
| `scraped_at` | string | ISO 8601 UTC datetime this row was written |

### 🔥 Features
- 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 `framework` switch (`HORIZON`, `H2020`, or `ANY`).
- 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.hit` as 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=true` deep-fetches the project detail HTML page via parsel and replaces the truncated search-API objective with the full text; charged as `result-row-detailed` ($0.005) instead of `result-row` ($0.003).
- Exponential backoff with `Retry-After` honoured for `429` and `503` responses; max 5 attempts.
- `curl-cffi` with Chrome 131 TLS impersonation (ADR-0002 house default) — robust against any future CORDIS rate-limit tightening even though the endpoint is unauthenticated today.
- Apify Proxy support via the `BUYPROXIES94952` group (opt-in via `useProxy`).
- Pydantic v2 input + output models — `ResultRow.status` is validated against the live enum (`SIGNED`, `CLOSED`, `TERMINATED`); `country_filter` normalised to upper-case at validation.

### 💡 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 gender, country, and SME representation among coordinators across an entire framework programme.

### ⚙️ How to use it
1. Open the Actor input form on the Apify Console.
2. Pick exactly **one** input mode:
   - **Project IDs** — supply a list of `projectIds` (e.g. `["101069357"]`) for direct lookup.
   - **Search query** — set `searchQuery` to a free-text query (e.g. `"quantum computing"`).
   - **Programme filter** — set `programmeFilter` to a programme code (e.g. `"HORIZON.2.5"` or `"H2020-EU.1.1."`).
   - **Country filter** — set `countryFilter` to an ISO 3166-1 alpha-2 code (e.g. `"DE"`, `"ES"`, `"NL"`).
3. Pick a `framework` — `HORIZON` (default), `H2020`, or `ANY`. Ignored in `projectIds` mode.
4. Set `maxProjects` (1-5000) to cap the dataset size in list modes. Ignored in `projectIds` mode.
5. Toggle `includeFullAbstract` on if you need the full untruncated objective text — costs one extra request per row and switches PPE to `result-row-detailed`.
6. Toggle `useProxy` on if CORDIS starts returning `429`. Default is off — CORDIS does not currently rate-limit datacenter IPs.
7. Click **Start**. Results stream into the default dataset as JSON / CSV / Excel / XML.

#### Single project lookup

```json
{
  "projectIds": ["101069357"]
}
````

#### Free-text search, capped at 50 rows

```json
{
  "searchQuery": "quantum computing",
  "framework": "HORIZON",
  "maxProjects": 50
}
```

#### All German-coordinated HORIZON projects (post-filter)

```json
{
  "countryFilter": "DE",
  "framework": "HORIZON",
  "maxProjects": 500
}
```

### 📥 Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `projectIds` | string\[] | XOR | — | Explicit CORDIS project IDs to fetch. |
| `searchQuery` | string | XOR | — | Free-text search query (1-500 chars). |
| `programmeFilter` | string | XOR | — | Programme code (e.g. `HORIZON.2.5`). |
| `countryFilter` | string | XOR | — | ISO 3166-1 alpha-2 of coordinator country (e.g. `DE`). |
| `framework` | enum | no | `HORIZON` | `HORIZON`, `H2020`, or `ANY`. |
| `maxProjects` | integer | no | `100` | Max ResultRows emitted (1-5000). |
| `includeFullAbstract` | boolean | no | `false` | Deep-fetch full objective from detail page. |
| `useProxy` | boolean | no | `false` | Route via Apify Proxy (`BUYPROXIES94952`). |

Exactly one of `projectIds`, `searchQuery`, `programmeFilter`, or `countryFilter` must be provided. Passing zero or two+ raises a validation error before any network call.

### 📤 Output

One row per project, pushed to the default dataset and available as JSON, CSV, Excel, or XML.

```json
{
  "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"
}
```

#### Export formats

- **JSON** — full fidelity, all 20 fields, newline-delimited
- **CSV** — flat, one row per project (array fields joined)
- **Excel** — `.xlsx` via the Apify dataset converter
- **XML** — structured per-item

All formats are available via the Apify API: `GET /datasets/{id}/items?format=csv&clean=true`.

### 💰 Pricing

Pay-Per-Event (PPE) — you pay only for what you use:

| Event | Price (USD) | When |
|---|---|---|
| `actor-start` | $0.05 | Once per run, at boot |
| `result-row` | $0.003 | Per project row written when `includeFullAbstract=false` |
| `result-row-detailed` | $0.005 | Per project row written when `includeFullAbstract=true` |

#### Example costs

| Run | Rows | Mode | Cost |
|---|---|---|---|
| 1 project lookup | 1 | standard | $0.053 |
| 50 search results | 50 | standard | $0.20 |
| 500 programme rows | 500 | standard | $1.55 |
| 1,000 country-filtered rows | 1,000 | standard | $3.05 |
| 1,000 rows, full abstracts | 1,000 | detailed | $5.05 |

At scale the per-row charge dominates: ~$3.05 per 1,000 rows in standard mode, ~$5.05 per 1,000 rows in detailed mode. Comparable NIH / NSF grant Actors run $1-3 per 1,000 records — EU grants are higher value per record due to larger deal sizes (median Horizon Europe grant ~2-3M EUR vs ~500k USD for typical NIH R01) and richer multi-organisation metadata.

### 🚧 Limitations

- **Public CORDIS search API only.** No authenticated CORDIS portal features, no My CORDIS saved searches, no Steamworks-style backstage endpoints.
- **HORIZON and H2020 only.** FP7 and earlier framework programmes are not indexed in the current CORDIS search; 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.
- **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, so country-filter mode may scan many more API pages than `maxProjects` to collect that many matching rows. API call count is uncapped; emitted row count is always `≤ maxProjects`.
- **Status filter is not a user input.** Live CORDIS data only emits `SIGNED`, `CLOSED`, or `TERMINATED`; the search API's status field path does not reliably filter — surfaced only on the output row.
- **Page size is fixed at 50.** CORDIS's `num=100` parameter returns only 10 results (verified 2026-05-16) — the Actor uses `num=50` everywhere 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

**Do I need an API key?**

No. The CORDIS search endpoint at `https://cordis.europa.eu/search/en?format=json` is fully public and unauthenticated. The Actor reads only data that the EU Commission already publishes openly.

**Why is the `objective_summary` cut off?**

The CORDIS search API returns the objective text truncated to ~2000 characters in search results. Set `includeFullAbstract=true` to make the Actor follow up with a per-project HTTP GET to the detail page (`/project/id/{id}/en`) and extract the untruncated objective via a `parsel` CSS selector. This switches the PPE event from `result-row` ($0.003) to `result-row-detailed` ($0.005) per row.

**Why is the country filter so slow?**

CORDIS's search API does not expose coordinator country as a query field — `coordinator/country=DE` returns zero results (verified 2026-05-16). The Actor implements country filtering by post-filtering full search results: it scans pages of all-framework projects and keeps only rows where `coordinator_country == countryFilter`. To collect `maxProjects=500` German projects, the Actor may scan 1500+ projects total. The emitted dataset row count is always `≤ maxProjects`.

**Can I filter by project status (SIGNED / CLOSED / TERMINATED)?**

Not as a direct input — CORDIS's search API status field path does not produce reliable filtered results. Status is emitted on every output row, so you can filter the dataset client-side after the run.

**What about FP7 or earlier frameworks?**

Out of scope. The current CORDIS search index covers HORIZON (Horizon Europe, 2021-2027) and H2020 (Horizon 2020, 2014-2020) only. The Actor will return zero rows for any FP6-and-earlier query.

**Are CORDIS results free to redistribute?**

Yes, under CC-BY 4.0 (EU Open Data policy). Attribution to the European Commission's CORDIS service is required.

### Related Actors

Part of the Devil Scrapes **Research Intelligence Suite**:

- **arXiv Papers Scraper** — preprint metadata across all arXiv categories.
- **PubMed Papers Scraper** — biomedical literature from the NIH PubMed index.
- **SEC EDGAR Filings Scraper** — US public-company filings for company funding context.
- **USPTO Patents Scraper** — US patent metadata for IP landscape work.
- **Hugging Face Hub Scraper** — model and dataset metadata for AI research overlap.

All suite Actors share consistent PPE pricing ($0.001-$0.005 per row, $0.01-$0.05 per run) and `scraped_at` ISO 8601 UTC timestamps so cross-source joins work cleanly.

### 💬 Your feedback

Found a bug, hit a rate limit, or need a new field on the output row? Open an issue on the Actor's Apify Store page or contact the Devil Scrapes team at [apify.com/DevilScrapes](https://apify.com/DevilScrapes). We ship updates within days of validated reports.

# Actor input Schema

## `projectIds` (type: `array`):

Explicit CORDIS project IDs to fetch (e.g. <code>101069357</code>). Exactly one of <code>projectIds</code>, <code>searchQuery</code>, <code>programmeFilter</code>, or <code>countryFilter</code> must be provided.

## `searchQuery` (type: `string`):

Free-text query against the CORDIS search index (e.g. <code>quantum computing</code> or <code>hydrogen storage</code>). 1-500 chars.

## `programmeFilter` (type: `string`):

Programme code, e.g. <code>HORIZON.2.5</code> (Climate, Energy and Mobility) or <code>H2020-EU.1.1.</code> (ERC).

## `countryFilter` (type: `string`):

ISO 3166-1 alpha-2 of the coordinator country (e.g. <code>DE</code>, <code>ES</code>, <code>NL</code>). Lower-case is normalised to upper. Implemented as a post-filter on search results — pagination may scan more API pages than <code>maxProjects</code> to collect that many matching rows.

## `framework` (type: `string`):

Restrict to one framework programme or search both. Ignored when <code>projectIds</code> mode is used.

## `maxProjects` (type: `integer`):

Max ResultRows emitted in list modes (search, programme, country). Ignored when <code>projectIds</code> mode is used.

## `includeFullAbstract` (type: `boolean`):

Deep-fetch the project detail HTML page to extract the untruncated objective text. Adds one extra request per row and switches PPE event from <code>result-row</code> ($0.003) to <code>result-row-detailed</code> ($0.005).

## `useProxy` (type: `boolean`):

Route requests through Apify Proxy (<code>BUYPROXIES94952</code>). CORDIS does not currently rate-limit datacenter IPs; leave off unless you see <code>429</code>.

## Actor input object example

```json
{
  "projectIds": [
    "101069357",
    "101082359"
  ],
  "searchQuery": "quantum computing",
  "programmeFilter": "HORIZON.2.5",
  "countryFilter": "DE",
  "framework": "HORIZON",
  "maxProjects": 100,
  "includeFullAbstract": false,
  "useProxy": false
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All dataset items as JSON.

## `datasetItemsCsv` (type: `string`):

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "quantum computing"
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/eu-cordis-grants").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "searchQuery": "quantum computing" }

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/eu-cordis-grants").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "quantum computing"
}' |
apify call devilscrapes/eu-cordis-grants --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=devilscrapes/eu-cordis-grants",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "EU CORDIS Grants Scraper",
        "description": "Scrape EU CORDIS — the European Commission's R&D project database. Get grants, participants, funding amounts, topics, and project IDs as typed dataset rows. We handle pagination, retries, and rate-limit pacing across CORDIS's federated endpoints.",
        "version": "0.3",
        "x-build-id": "Ufrh4ISfUfb7keoLY"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/devilscrapes~eu-cordis-grants/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-devilscrapes-eu-cordis-grants",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/devilscrapes~eu-cordis-grants/runs": {
            "post": {
                "operationId": "runs-sync-devilscrapes-eu-cordis-grants",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/devilscrapes~eu-cordis-grants/run-sync": {
            "post": {
                "operationId": "run-sync-devilscrapes-eu-cordis-grants",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "projectIds": {
                        "title": "Project IDs",
                        "type": "array",
                        "description": "Explicit CORDIS project IDs to fetch (e.g. <code>101069357</code>). Exactly one of <code>projectIds</code>, <code>searchQuery</code>, <code>programmeFilter</code>, or <code>countryFilter</code> must be provided.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchQuery": {
                        "title": "Free-text search",
                        "type": "string",
                        "description": "Free-text query against the CORDIS search index (e.g. <code>quantum computing</code> or <code>hydrogen storage</code>). 1-500 chars."
                    },
                    "programmeFilter": {
                        "title": "Programme filter",
                        "type": "string",
                        "description": "Programme code, e.g. <code>HORIZON.2.5</code> (Climate, Energy and Mobility) or <code>H2020-EU.1.1.</code> (ERC)."
                    },
                    "countryFilter": {
                        "title": "Coordinator country (ISO-2)",
                        "type": "string",
                        "description": "ISO 3166-1 alpha-2 of the coordinator country (e.g. <code>DE</code>, <code>ES</code>, <code>NL</code>). Lower-case is normalised to upper. Implemented as a post-filter on search results — pagination may scan more API pages than <code>maxProjects</code> to collect that many matching rows."
                    },
                    "framework": {
                        "title": "Framework programme",
                        "enum": [
                            "HORIZON",
                            "H2020",
                            "ANY"
                        ],
                        "type": "string",
                        "description": "Restrict to one framework programme or search both. Ignored when <code>projectIds</code> mode is used.",
                        "default": "HORIZON"
                    },
                    "maxProjects": {
                        "title": "Max projects",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Max ResultRows emitted in list modes (search, programme, country). Ignored when <code>projectIds</code> mode is used.",
                        "default": 100
                    },
                    "includeFullAbstract": {
                        "title": "Include full objective",
                        "type": "boolean",
                        "description": "Deep-fetch the project detail HTML page to extract the untruncated objective text. Adds one extra request per row and switches PPE event from <code>result-row</code> ($0.003) to <code>result-row-detailed</code> ($0.005).",
                        "default": false
                    },
                    "useProxy": {
                        "title": "Use Apify Proxy",
                        "type": "boolean",
                        "description": "Route requests through Apify Proxy (<code>BUYPROXIES94952</code>). CORDIS does not currently rate-limit datacenter IPs; leave off unless you see <code>429</code>.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
