# EU Funding & Tender Opportunities (Grants) – Calls & Deadlines (`shadow-tools/eu-funding-tender-opportunities-grants`) Actor

Search and monitor EU grant calls from the Funding & Tenders Portal: Horizon Europe, Digital Europe, LIFE, Erasmus+, CEF and more. Deadlines, budgets, action types, official link. No personal data. Unofficial, built on the public search API.

- **URL**: https://apify.com/shadow-tools/eu-funding-tender-opportunities-grants.md
- **Developed by:** [Shadow Tools](https://apify.com/shadow-tools) (community)
- **Categories:** Lead generation, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 funding calls

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## EU Funding & Tender Opportunities (Grants) – Calls & Deadlines

Call this Actor to find **EU grant calls** (money you apply for, not contracts you bid for) from the EU Funding & Tenders Portal: Horizon Europe, Digital Europe, LIFE, Erasmus+, CEF, Creative Europe, EDF and many more programmes. One record per call or topic, with **identifier, programme, status, opening date, deadlines, budget, grant size, type of action and the official link**. Use `search` for a question right now ("which AI calls are open and close before March?"), and `monitor` only for scheduled runs (it returns only calls that are new or changed since the last run).

> **Unofficial tool. Not affiliated with, endorsed by or sponsored by the European Commission.** It reads the portal's public search API and reformats the result. Always check the official call page and the work programme before applying.

#### Minimal input per mode

| Mode | Minimal input | What comes back |
|---|---|---|
| `search` | `{"keywords": ["artificial intelligence"], "maxResults": 5}` | open and forthcoming calls matching the words, soonest deadline first |
| `search` (by programme and window) | `{"programmes": ["LIFE", "DIGITAL"], "deadlineFrom": "2026-12-01", "deadlineTo": "2027-03-31"}` | calls of those programmes with a deadline in the window |
| `search` (one known topic) | `{"topicIdentifiers": ["HORIZON-CL3-2027-02-CS-ECCC-01"]}` | its status, deadline and budget |
| `monitor` | `{"mode": "monitor", "programmes": ["HORIZON"], "keywords": ["quantum"]}` | only calls new or changed (status, deadline, budget, title) since the last run with the same filters |

An empty input `{}` is valid: it returns the 20 open or forthcoming calls with the nearest deadline.

Short output (real record, 5 Nov 2026, summary shortened):

```json
{"id": "HORIZON-CL3-2027-02-CS-ECCC-01", "kind": "topic", "title": "Artificial Intelligence for Cybersecurity applications", "programme": "HORIZON", "status": "forthcoming", "actionType": "HORIZON Research and Innovation Actions", "openingDate": "2027-03-02", "nextDeadline": "2027-09-15", "daysToDeadline": 314, "budget": 24800000, "currency": "EUR", "minGrant": 4000000, "maxGrant": 5000000, "expectedGrants": 5, "summary": "Expected Outcome: Proposals are expected to contribute to one or more of the following: AI-driven solutions for real-time cyber threat detec...", "url": "https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/opportunities/topic-details/HORIZON-CL3-2027-02-CS-ECCC-01"}
```

#### For AI agents (MCP)

- **One call = one answer.** Default `maxResults` is 20. Keep it small; raise it only when the run SUMMARY `note` says more calls match. A typical run takes 2-20 s (the whole portal list is read, then sorted by deadline).
- **Pick the mode by intent**: `search` to answer a question now; `monitor` only on a schedule. For one known topic code use `topicIdentifiers`.
- **Errors fail fast** as `Field X invalid: expected Y, got Z, example W` (for example `Field deadlineFrom invalid: expected a real date YYYY-MM-DD, got "05/11/2026", example 2026-12-01.`). Fix that field and call again; nothing is charged.
- **0 results is not an error.** The run succeeds with an empty dataset and the key-value store record `SUMMARY` carries a `note` telling why and how to widen (fewer keywords, other programmes, `includeExpired`, wider deadline window). The same `note` is written when a result is capped, partial or stopped by the cost cap.
- **Keywords are English**: several keywords are alternatives (OR); the words inside one keyword must all appear (AND).
- **`daysToDeadline`** and **`nextDeadline`** are computed at run time; deadlines are calendar dates as published by the portal (time of day is not returned; the portal shows Brussels time).
- Free text (`summary`) is optional and privacy-filtered: it can be `null` even for a real call (see below). Never rely on it for eligibility: open `url`.

### How it complements "Open Tenders Daily – BOAMP + TED"

| | **This Actor** | Open Tenders Daily (BOAMP + TED) |
|---|---|---|
| What | **Grants**: funding you apply for (research, innovation, culture, environment, defence R\&D...) | **Procurement tenders**: contracts a public buyer wants to award (supplies, services, works) |
| Source | EU Funding & Tenders Portal (grant calls and topics) | BOAMP (France), TED (EU), Contracts Finder / Find a Tender (UK) |
| Audience | Research labs, SMEs, NGOs, consultants, grant writers | Suppliers and bidders |
| Deadline logic | Call deadlines, multi-cut-off calls, forthcoming calls | Notice deadlines |

Procurement notices are deliberately **not** returned here, so the two Actors never return the same record.

### Who uses it

- **Grant consultants and EU project offices**: a weekly digest of new or changed calls in the programmes you cover (`monitor` on a schedule).
- **Research labs and universities**: calls with a deadline in the next three months and a minimum budget.
- **SMEs and start-ups**: small calls for third parties (cascade funding), often small amounts, found with `kinds: ["competitive-call"]`.
- **Regional agencies and clusters**: tell members which calls open, with the official link.
- **Developers and AI agents**: feed a CRM, a chat channel or a funding assistant through the API or the MCP server.

### Modes

- **search**: calls matching your filters, soonest upcoming deadline first (or by relevance / opening date). `onlyNew: true` turns a search into an incremental one.
- **monitor**: only calls **new** (`change: "new"`) or **changed** (`change: "updated"` and `changedFields`, among `status`, `deadlines`, `openingDate`, `budget`, `title`, `actionType`) since a previous run with the same filters. The first monitor run returns the current matching calls (up to `maxResults`). State is kept in a named key-value store per Actor and user, per filter set.

Filters (all optional, combined with AND; several values inside one filter are OR): `keywords`, `programmes`, `status`, `kinds`, `actionTypes`, `callIdentifiers`, `topicIdentifiers`, `deadlineFrom`/`deadlineTo`, `minBudget`.

**Kinds**: `topic` (a topic of an EU work programme: the main grants), `competitive-call` (a call for third parties launched by an already funded project: cascade funding), `external-aid` (EU external-action calls from the Prospect system).

### Data quality: stale "open" and "forthcoming" entries are hidden by default

On 5 Nov 2026 the portal listed 1,204 calls as open or forthcoming, but **659 of the 1,192 usable ones had every deadline in the past** (for example topics from 2024 still marked "forthcoming"). The Actor hides them unless you set `includeExpired: true`, so a default run shows calls you can still apply to. Calls with no published deadline stay visible.

### What you get

`source`, `kind`, `id` (topic or call identifier; not unique for `competitive-call`, use `uid`), `uid`, `callIdentifier`, `title`, `callTitle`, `programme`, `programmeCode`, `programmePeriod`, `status` (open / forthcoming / closed), `actionType`, `submissionProcedure` (single-stage, two-stage, multiple cut-off...), `openingDate`, `deadlines[]`, `nextDeadline`, `daysToDeadline`, `budget`, `currency`, `minGrant`, `maxGrant`, `expectedGrants`, `summary`, `topics[]`, `url` (**official call page**), `matchedKeywords[]`, `change` and `changedFields[]` (monitor), `attribution`, `extractedAt`.

Budget notes: for a `topic`, `budget` is the indicative total of that topic from the call's budget table (no guess at call level: `null` if the portal has no line for it); `minGrant`, `maxGrant` and `expectedGrants` are `null` when the portal publishes `0` (lump-sum topics). Erasmus+ main calls are published on the Erasmus+ site and only a few appear on this portal.

### Privacy / GDPR by design

**The Actor returns no data about natural persons, and the filtering below is applied on purpose to respect the GDPR.** Funding calls are institutional documents, but the portal's call pages also carry support mailboxes and sometimes names of programme officers, coordinators or speakers. None of this is output.

How it works (fail closed):

1. **Allow-list.** Every record is built field by field from a fixed list of structured fields (identifier, titles, programme, action type, status, dates, amounts, official URL). Every other field the API returns, such as support information, contact details, project administration texts or any field added later, is dropped. A test proves that an invented personal field never reaches the output.
2. **Free text.** The only free text kept is a short `summary` of a topic description (600 characters at most). It is cut at the first contact marker ("contact", "for further information", "e-mail", "phone", "coordinator", "project officer", "speaker"...), and the **whole text is dropped** when anything that looks like an e-mail, a phone number or a titled person (Dr, Prof...) remains. Calls for third parties and external-action calls have no free text at all.
3. **Last guard.** Every string of the finished record is checked again for e-mail, phone and person patterns; a hit blanks the field.
4. **Nothing about you is stored.** The Actor keeps no information about who runs it. The only state is a list of call identifiers with a short fingerprint (status, deadlines, budget...) in your own Apify key-value store, used by `monitor`.

Measured on 5 Nov 2026: on the 1,001 open and forthcoming topics, 409 had a description; 49 were cut at a contact marker, 1 was dropped entirely; on 2,877 closed topics, 379 were cut and 55 dropped; **0 e-mail, phone or titled-person pattern remained in any output** (`scripts/rgpd-measure.js`).

**Residual risk, stated plainly**: pattern filters cannot prove the absence of every name. Official titles can contain the name of a historical person (for example an action named after a scientist), and a descriptive sentence could in theory name a living person without an e-mail, a phone number or a title next to it. The cut at contact markers also removes some harmless text that follows the word "contact" or "coordinator". Check the official page for complete information.

### Data source, licence and terms

- Source: the public search API of the EU Funding & Tenders Portal (`api.tech.ec.europa.eu/search-api`), documented by the Commission on the portal's APIs page ("public REST APIs where any external system can call"). No key is needed beyond the public portal key; no account, no login.
- Reuse: © European Union. The Commission's legal notice states that, unless otherwise indicated, content owned by the EU is licensed **CC BY 4.0** (reuse allowed with credit and indication of changes) and that its reuse policy is Commission Decision 2011/833/EU. Every record carries an `attribution` with the source and the date, and says that fields were selected and reformatted. The portal API terms were not found as a separate text; the legal notice above is what was read.
- The Commission accepts no responsibility for the accuracy of the information and only the official publications are authentic. This Actor adds no warranty either.

### Pricing

Pay per event, no subscription:

| Event | Price | Per 1,000 |
|---|---|---|
| `funding-call`: one call delivered (one dataset record) | **0.01 USD** | **10 USD per 1,000 calls** |
| Actor start (once per run) | platform default | n/a |

A run that returns nothing costs only the start event. You can cap spend per run with the platform's **Maximum cost per run**: the Actor reads it, stops cleanly when the cap is reached and returns what it already delivered. In `monitor` mode, calls not delivered because of the cap are not marked as seen: they stay "new" for the next run.

### FAQ

- **Is this the official API?** No. It uses the portal's public API and returns a cleaned, privacy-filtered subset. The official pages remain the reference.
- **Why do I get fewer calls than the portal shows?** Stale entries are hidden (see above), and only grant calls are returned, not procurement tenders.
- **Why is `summary` null?** Many calls have no description in the API, and descriptions that might carry contact data are dropped on purpose.
- **How fresh is it?** Read live at each run.
- **Closed calls?** Add `"status": ["closed"]` with programmes or keywords; the run reads at most the 3,000 most recent records (the note says when the limit applies).

### En bref (français)

Acteur non officiel qui lit l'API publique du portail Funding & Tenders de l'UE : appels à propositions (subventions) Horizon Europe, Digital Europe, LIFE, etc., avec échéances, budget, type d'action et lien officiel. Mode `search` pour une question ponctuelle, `monitor` pour surveiller les appels nouveaux ou modifiés. Aucune donnée sur des personnes physiques n'est restituée (e-mails, téléphones et noms retirés, filtrage appliqué volontairement pour respecter le RGPD).

# Actor input Schema

## `mode` (type: `string`):

Pick one. "search" = use for a question about funding calls right now (which calls are open for topic X, which close before a date): returns the calls matching your filters, soonest deadline first. "monitor" = use only for scheduled (daily or weekly) runs: returns only calls that are NEW or CHANGED (status, deadline, budget, title) since a previous run with the same filters; the first monitor run returns the current matching calls. Allowed values: search, monitor. Default: search.

## `keywords` (type: `array`):

English words searched in the full text of the call, as a list, e.g. \["artificial intelligence", "quantum"]. ANY keyword matches (OR); all the words of a keyword with several words must appear (AND), not necessarily next to each other. Empty = no keyword filter. Use specific words; very general ones ("AI") also match boilerplate text.

## `programmes` (type: `array`):

EU funding programmes to include, as a list of codes, e.g. \["HORIZON", "DIGITAL", "LIFE"]. Common codes: HORIZON = Horizon Europe (research and innovation), DIGITAL = Digital Europe, LIFE = environment and climate, ERASMUS = Erasmus+ (only the calls published on this portal), CEF = Connecting Europe Facility, EDF = European Defence Fund, CREA = Creative Europe, CERV = citizens, equality, rights and values, EU4H = EU4Health. Empty = all programmes.

## `status` (type: `array`):

Status of the calls to return, as a list, e.g. \["open", "forthcoming"]. Allowed values: open (accepting proposals now), forthcoming (announced, not yet open), closed (past calls, useful for history; there are thousands, so combine with programmes or keywords). Default: open and forthcoming.

## `kinds` (type: `array`):

Kinds of call to include, as a list, e.g. \["topic"]. Allowed values: topic (a topic of an EU work programme, the main grants), competitive-call (a call for third parties launched by an already funded project, often small amounts, also called cascade funding or financial support to third parties), external-aid (EU external-action grant calls, Prospect/EuropeAid). Default: all three.

## `actionTypes` (type: `array`):

Words that must appear in the type of action, as a list, e.g. \["Innovation Actions", "Coordination and Support"]. ANY matches (OR), case ignored. Typical types: Research and Innovation Actions, Innovation Actions, Coordination and Support Actions, Project Grants, Lump Sum Grant. Empty = all types.

## `callIdentifiers` (type: `array`):

Exact identifiers of calls (a call groups several topics), as a list, e.g. \["HORIZON-CL3-2027-01"]. Use to restrict to one work-programme call. Empty = no restriction.

## `topicIdentifiers` (type: `array`):

Exact identifiers of topics, as a list, e.g. \["HORIZON-CL3-2027-02-CS-ECCC-01"]. Use when you already know the topic code and want its deadline, budget and status. Include status closed if the topic may be past. Empty = no restriction.

## `deadlineFrom` (type: `string`):

Keep calls having at least one deadline on or after this date, format YYYY-MM-DD, e.g. 2026-12-01. Empty = no lower bound. Deadlines are calendar dates as published by the portal.

## `deadlineTo` (type: `string`):

Keep calls having at least one deadline on or before this date, format YYYY-MM-DD, e.g. 2027-03-31. Empty = no upper bound. Combine with deadlineFrom for a window.

## `minBudget` (type: `integer`):

Keep calls whose published total budget is at least this many euros, as an integer, e.g. 5000000. Calls without a published budget are excluded when this is set. Empty = no budget filter.

## `includeExpired` (type: `boolean`):

If true, also return calls the portal still marks open or forthcoming although every deadline has passed (continuous or stale entries). Default false: such calls are hidden.

## `sortBy` (type: `string`):

Order of the results. Allowed values: deadline (soonest upcoming deadline first), relevance (best keyword match first, needs keywords), newest (most recent opening date first). Default: deadline.

## `onlyNew` (type: `boolean`):

If true, a search returns only calls not delivered before (or whose status, deadline, budget or title changed) for the same filters; state is kept per Actor and user store. Default false, so a plain run always returns data. Monitor mode always behaves like this.

## `maxResults` (type: `integer`):

Maximum number of calls to return, as an integer from 1 to 5000, e.g. 20. Keep it small for agents; the run summary says when more calls match. Each returned call is one billed result.

## Actor input object example

```json
{
  "mode": "search",
  "keywords": [
    "artificial intelligence"
  ],
  "programmes": [
    "HORIZON",
    "DIGITAL"
  ],
  "status": [
    "open"
  ],
  "kinds": [
    "topic"
  ],
  "actionTypes": [
    "Innovation Actions"
  ],
  "callIdentifiers": [
    "HORIZON-CL3-2027-01"
  ],
  "topicIdentifiers": [
    "HORIZON-CL3-2027-02-CS-ECCC-01"
  ],
  "includeExpired": false,
  "sortBy": "deadline",
  "onlyNew": false,
  "maxResults": 20
}
```

# Actor output Schema

## `calls` (type: `string`):

Matching calls with programme, status, deadline, budget, type of action and official link.

## `dataset` (type: `string`):

Every field of every call, downloadable as JSON, CSV or Excel.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("shadow-tools/eu-funding-tender-opportunities-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("shadow-tools/eu-funding-tender-opportunities-grants").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{}' |
apify call shadow-tools/eu-funding-tender-opportunities-grants --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,shadow-tools/eu-funding-tender-opportunities-grants"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/yBlxIb1DzPQR2Oo6T/builds/k58NUGJ2BYlERcQPB/openapi.json
