# EU Tenders Scraper (TED API): open tenders by country & CPV (`timeout/ted-eu-tenders-search`) Actor

Open EU public tenders from the official TED API as clean rows: buyer, country, deadline, value, CPV, link. Filter by country, keyword and CPV; get only new tenders each run. No API key.

- **URL**: https://apify.com/timeout/ted-eu-tenders-search.md
- **Developed by:** [Cesar Rodriguez](https://apify.com/timeout) (community)
- **Categories:** Business, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 tender results

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 Public Tenders (TED) Scraper & API — open tenders by country, CPV and keyword

Get **open EU public procurement tenders** as clean JSON, CSV or Excel straight from the official **TED (Tenders Electronic Daily)** API. No API key, no proxies, no browser, so runs are fast and cheap.

Filter by **buyer country**, **keywords** in the notice title and **CPV code** prefixes. Every row has: publication number, title (in your preferred language), buyer, country, publication date, submission deadline, estimated value + currency (when published), CPV codes, notice type, a direct link to the official notice and the required attribution.

### What can I do with it?

- **Tender alerts**: schedule the Actor daily or weekly with `onlyNewSinceLastRun` and each run returns only notices you have not received before. Send them on with Apify integrations (email, Slack, Google Sheets, webhooks, Zapier, Make, n8n).
- **Find bids for your company**: IT and software (CPV `72`, `48`), construction (`45`), consulting (`79`), medical equipment (`33`), transport (`60`)...
- **Lead lists for sales teams**: which public buyers are purchasing what, and until when.
- **Procurement analytics**: tender volumes by country, buyer or CPV division.
- **AI agents / MCP / n8n**: one action with a clear input schema, e.g. "open tenders in Germany about software, last 7 days".

### Input

| Field | Description |
|---|---|
| `countries` | Buyer countries, ISO-3166 alpha-3 (`DEU`, `ESP`, `FRA`, `ITA`, `POL`...). Empty = all countries in TED. |
| `keywords` | Match in notice title (any keyword). Use the language of the notices, e.g. `software`, `Wartung`, `consultoría`. |
| `cpvPrefixes` | CPV code prefixes, e.g. `72` (IT services), `48` (software packages), `45` (construction). |
| `daysBack` | Notices published in the last N days (1–90). |
| `onlyOpen` | Skip tenders whose submission deadline has already passed. |
| `callsOnly` | Only open calls for tender (contract notices), no award or modification notices. |
| `onlyNewSinceLastRun` | Return only notices not delivered in earlier runs of the same `feedName`. |
| `feedName` | Name of the feed, so you can keep separate alerts (e.g. `it-germany`, `construction-spain`). |
| `language` | Preferred title language (`eng`, `deu`, `spa`, `fra`...). |
| `maxItems` | Maximum number of results (1–5000). |

Example input — software tenders in Germany and Spain, new ones only:

```json
{ "countries": ["DEU", "ESP"], "keywords": ["software"], "cpvPrefixes": ["72"], "daysBack": 7, "onlyNewSinceLastRun": true, "feedName": "software-de-es", "maxItems": 100 }
```

### Output example

```json
{
  "publicationNumber": "704142-2026",
  "title": "Germany – Financial analysis and accounting software package – …",
  "buyer": "Hochschule RheinMain, Die Präsidentin",
  "country": "DEU",
  "publicationDate": "2026-10-13",
  "deadline": "2026-11-12",
  "estimatedValue": null,
  "currency": null,
  "cpv": ["48440000"],
  "noticeType": "cn-standard",
  "url": "https://ted.europa.eu/en/notice/-/detail/704142-2026",
  "attribution": "Data: TED (Tenders Electronic Daily), © European Union, CC BY 4.0"
}
```

`estimatedValue` is `null` when the buyer did not publish a value (often the case).

### FAQ

**Do I need a TED API key or account?** No. This Actor uses the public TED search API, which needs no key.

**Does it cover all EU countries?** It queries TED, which publishes notices from EU member states and other participating countries. Use `countries` to narrow down; leave it empty for everything.

**How fresh is the data?** As fresh as TED itself: notices appear on TED after publication by the Publications Office of the EU, usually within days of the buyer's submission. Always verify details on the official notice (`url`) before bidding.

**What is `onlyNewSinceLastRun` exactly?** The Actor remembers the publication numbers it delivered for each `feedName` (stored in a key-value store in your Apify account) and skips them next time. You are charged only for rows delivered.

**Does it download tender documents or buyer contact details?** No. It returns notice metadata and a link to the official notice.

**Can I filter by value?** Not yet. Estimated values are only published for part of the notices; the field is included when available.

**Which formats can I export?** JSON, CSV, Excel, XML, HTML and RSS from the dataset, or use the Apify API.

### Pricing

Pay per event: **$0.003 per tender result** + **$0.00005 per run start** (e.g. 1,000 tenders ≈ $3.00). You only pay for rows delivered to your dataset.

### Data source, licence and attribution

Data comes from the public TED API (api.ted.europa.eu), © European Union, reused under **CC BY 4.0**. Every row carries the attribution *"Data: TED (Tenders Electronic Daily), © European Union, CC BY 4.0"* — keep it if you republish the data. This Actor is an independent tool and is **not affiliated with or endorsed by** the European Union or the Publications Office of the EU.

### Support

Found a bug or need another field? Open an issue from the Actor's *Issues* tab.

# Actor input Schema

## `countries` (type: `array`):

E.g. DEU, ESP, FRA. Empty = all EU.

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

Match in notice title (any keyword). Example: software, Wartung, consultoría.

## `cpvPrefixes` (type: `array`):

E.g. 72 (IT services), 48 (software packages), 45 (construction).

## `daysBack` (type: `integer`):

Only notices published within the last N days (1-90).

## `onlyOpen` (type: `boolean`):

Skip tenders whose submission deadline is already in the past.

## `callsOnly` (type: `boolean`):

Excludes award/modification notices.

## `language` (type: `string`):

Preferred language for titles and buyer names, as a 3-letter code (eng, deu, spa, fra...). Falls back to English or any available language.

## `onlyNewSinceLastRun` (type: `boolean`):

Schedule the Actor daily/weekly and each run returns only notices you have not received before (per feed name). You are charged only for the rows delivered.

## `feedName` (type: `string`):

Separate 'already delivered' memory per feed, e.g. 'it-germany' and 'construction-spain'.

## `maxItems` (type: `integer`):

Maximum number of tenders to return (1-5000).

## Actor input object example

```json
{
  "countries": [
    "DEU"
  ],
  "keywords": [],
  "cpvPrefixes": [],
  "daysBack": 7,
  "onlyOpen": true,
  "callsOnly": true,
  "language": "eng",
  "onlyNewSinceLastRun": false,
  "feedName": "default",
  "maxItems": 100
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items (JSON/CSV/Excel via the API format parameter).

# 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("timeout/ted-eu-tenders-search").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("timeout/ted-eu-tenders-search").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 timeout/ted-eu-tenders-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,timeout/ted-eu-tenders-search"
        }
    }
}
```

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/JeTPXupSYKZ0CJ7WQ/builds/MEcc1vzarmWWDyf5d/openapi.json
