# EU Tenders Scraper — TED Procurement Notices & Awards (`publicdata/ted-eu-public-tenders`) Actor

Scrape EU tenders and procurement notices from TED (Tenders Electronic Daily): European public tender notices and contract awards from all EU countries plus Switzerland, with buyer, CPV codes, deadlines, estimated value and winners. Export to JSON, CSV or Excel; schedule a daily feed.

- **URL**: https://apify.com/publicdata/ted-eu-public-tenders.md
- **Developed by:** [Riccardo](https://apify.com/publicdata) (community)
- **Categories:** Business, Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## EU Public Tenders (TED) — search, monitor & export

**Stop checking the TED portal by hand: get every EU tender that matches your country, sector and keywords delivered as a structured file — and see who won the comparable contracts, and for how much.**

This Actor turns TED (Tenders Electronic Daily), the official journal of European public procurement, into a filtered JSON, CSV or Excel feed. It covers the contract notices and contract awards published by every EU member state, the EEA countries and Switzerland (Swiss GPA notices appear on TED too — 11,584 of them in 2025), around 80,000 procurement notices a month. No login, no API key, no proxy.

It reads the official TED Search API v3 with **iteration paging**, so an export is not capped at the 15,000-result window of the web interface: a year of one country's construction tenders comes out in a single run, at roughly 1,000 notices a minute.

### What you get

Every notice is flattened into one row, ready for Sheets, a database or a BI tool.

**Identification and dates**

- `publicationNumber` — the TED publication number, and a natural deduplication key
- `publicationDate`, `noticeType` (`cn-standard`, `can-standard`, `pin-only`, `qu-sy` …) and `noticeTypeLabel`, the plain-English version

**What is being bought**

- `title` and `description` in your preferred language, falling back to the notice's own language when no translation exists
- `cpvMain` and `cpvCodes` — the full Common Procurement Vocabulary list
- `contractNature` (works, supplies or services) and `procedureType` (open, restricted, negotiated …)

**Who is buying, and where the work happens**

- `buyerName`, `buyerCity`, `buyerCountry` (ISO-3)
- `placeOfPerformanceNuts` — NUTS region codes

**The two fields that decide whether you bid**

- **`estimatedValue`** with `currency`
- **`offerDeadline`** — the deadline for receipt of tenders

**On award notices, the competitive intelligence**

- **`winnerNames`** and `winnerCountries`
- `awardDecisionDate` and **`totalValue`**, the amount actually awarded

**Links and provenance**

- `pdfUrl` and `xmlUrl` — the official notice documents in your chosen language edition
- `tedUrl` — the notice page on ted.europa.eu
- `source` — carried on every record for attribution

### Who uses this

- A **bid manager** at a construction or IT firm runs a daily feed of new tender notices for two countries and three CPV families, and reads the deadlines before the competition does.
- A **sales lead** pulls award notices for their sector to see which rivals win which buyers, and at what price.
- A **compliance or public-affairs analyst** checks whether a counterparty appears as a winner of public contracts, and in which member states.
- A **researcher or journalist** exports several years of European public procurement notices for one CPV branch and compares values by country.
- An **AI agent or developer** calls the Actor as an MCP tool or over the API and passes a raw TED expert query, using the full search grammar without writing a TED client.

### Example output

A contract notice (tender you can still bid on):

```json
{
  "publicationNumber": "575842-2026",
  "publicationDate": "2026-08-20",
  "noticeType": "cn-standard",
  "noticeTypeLabel": "Contract notice",
  "title": "Italia – Apparecchi per mammografia – Fornitura di mammografi digitali",
  "buyerName": "AZIENDA SANITARIA PROVINCIALE DI CATANIA",
  "buyerCountry": "ITA",
  "cpvMain": "33124110",
  "cpvCodes": ["33124110"],
  "contractNature": "supplies",
  "procedureType": "open",
  "estimatedValue": 1360000.0,
  "currency": "EUR",
  "offerDeadline": "2026-10-06",
  "placeOfPerformanceNuts": ["ITG17"],
  "tedUrl": "https://ted.europa.eu/it/notice/575842-2026",
  "source": "TED (Tenders Electronic Daily), Publications Office of the EU"
}
```

An award notice adds the result of the competition:

```json
{
  "noticeTypeLabel": "Contract award notice",
  "winnerNames": "Dolomiti Energia Mercato SpA",
  "winnerCountries": ["ITA"],
  "awardDecisionDate": "2026-07-30",
  "totalValue": 89380900.0,
  "currency": "EUR"
}
```

### Input

| Field | What it does |
|---|---|
| `noticeGroup` | `tenders` (open competitions, default), `awards` (winners and values), `planning` (prior information notices), `all`. |
| `buyerCountries` | ISO-3 codes of the contracting authority: `ITA`, `DEU`, `FRA`, `CHE`, `AUT`, `ESP` … Empty means all countries. |
| `cpvCodes` | Full CPV codes (`45000000`) or wildcard prefixes: `45*` construction, `72*` IT services, `33*` medical, `34*` transport equipment. |
| `fullText` | Keyword(s) searched across the whole notice, using TED's `FT~` operator (any word form). |
| `publishedFrom` / `publishedUntil` | Date window, `YYYY-MM-DD`. Default: the last 7 days. |
| `expertQuery` | A raw TED expert query for full control. When set, the filters above are ignored. |
| `language` | Preferred language for titles, descriptions and the PDF link. Default `en`. |
| `maxItems` | Safety cap. Default 500; `0` means unlimited, since iteration paging handles any size. |

Last week's Italian construction tenders, with Italian titles:

```json
{ "noticeGroup": "tenders", "buyerCountries": ["ITA"], "cpvCodes": ["45*"], "language": "it" }
```

Who has been winning IT contracts in Germany and Austria this year — every award, no cap:

```json
{
  "noticeGroup": "awards",
  "buyerCountries": ["DEU", "AUT"],
  "cpvCodes": ["72*"],
  "publishedFrom": "2026-01-01",
  "language": "de",
  "maxItems": 0
}
```

Anything the TED expert search supports, passed through untouched:

```json
{ "expertQuery": "(buyer-country=ITA) AND (FT~(\"fotovoltaico\")) AND (publication-date>=20260101) SORT BY publication-date DESC" }
```

### Run it on a schedule

Save your filters as a Task, leave the two date fields empty so each run covers the last 7 days, and schedule it daily — TED publishes on working days, so a daily feed catches everything.

Attach an Apify integration to the schedule and the results land where you already work: **Google Sheets**, **Slack**, **e-mail**, a **webhook** into your own system, or **Make** and **Zapier** for your CRM. Deduplicate on `publicationNumber`, which is unique and stable per notice, so a rolling 7-day window never produces the same tender twice.

### Use it from code or from an AI agent

Start a run and read the dataset through the Apify API or CLI, with JSON or CSV export straight from the dataset endpoint. The Actor is also exposed through the Apify MCP server, so an AI agent can call it as a tool — and `expertQuery` lets that agent express a precise question without a purpose-built public tenders API client.

### Pricing

Pay per event: a small fee for each notice exported, shown in the pricing box on this page. There is no browser and no proxy involved — only API calls — so Apify platform usage on top of that is negligible.

### Where the data comes from

Every record comes from the official TED Search API of the Publications Office of the European Union. TED data is free for commercial and non-commercial reuse under the Commission's open-data policy (Decision 2011/833/EU) with attribution to the source, and each record carries `source: TED (Tenders Electronic Daily), Publications Office of the EU`.

Honest limits: TED holds notices above the EU publication thresholds, so smaller contracts published only on national portals are not here. Notices appear on their publication day, not in real time. Winner and awarded-value fields are filled on award notices only. Tender documents, buyer contact details and lists of unsuccessful bidders are not in the API response; use `tedUrl` or `pdfUrl` for the full official notice. This Actor is independent and not affiliated with the EU institutions.

### Related Actors

Same engine, same official-source approach:

- [**AusTender (Australia)**](https://apify.com/publicdata/austender-australian-government-contracts) — federal contracts, winners and expiry dates
- [**UK Public Tenders**](https://apify.com/publicdata/uk-contracts-finder-find-a-tender) — Contracts Finder and Find a Tender in one run
- [**Swiss Public Tenders (simap.ch)** — tenders and awards with prices, bid counts and weighted criteria](https://apify.com/publicdata/simap-swiss-public-tenders)
- [**Swiss Commercial Register (SHAB)** — new companies, changes, deletions and bankruptcies](https://apify.com/publicdata/shab-swiss-company-gazette)
- [**France Company Register** — SIREN/SIRET, executives, official labels](https://apify.com/publicdata/france-company-register-scraper)
- [**GLEIF LEI** — LEI lookup, lapsed-LEI screening, parent companies](https://apify.com/publicdata/gleif-lei-scraper)
- [**Brazil CNPJ** — Receita Federal company data and partners](https://apify.com/publicdata/brazil-cnpj-lookup)

# Actor input Schema

## `noticeGroup` (type: `string`):

Tenders = open competitions you can bid on. Awards = results with winners and values (competitor intelligence). Planning = prior information notices.

## `buyerCountries` (type: `array`):

Three-letter country codes of the contracting authority, e.g. ITA, DEU, FRA, CHE (yes, Swiss GPA tenders are on TED too), AUT, ESP. Empty = all countries.

## `cpvCodes` (type: `array`):

Common Procurement Vocabulary codes. Full codes (45000000) or wildcard prefixes (45\*). Examples: 45\* construction, 72\* IT services, 33\* medical, 34\* transport equipment.

## `fullText` (type: `string`):

Optional keyword(s) searched in the whole notice, e.g. "ospedale", "software", "photovoltaic". Uses TED's FT~ operator (any word form).

## `publishedFrom` (type: `string`):

Default: 7 days ago.

## `publishedUntil` (type: `string`):

Only notices published on/before this day.

## `expertQuery` (type: `string`):

Optional raw TED expert-search query, e.g. (buyer-country=ITA) AND (classification-cpv IN (45\*)) AND (publication-date>=20260101). When set, all filter fields above are ignored except the date defaults.

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

Titles/descriptions are picked in this language when the notice provides it (fallback to the notice's own language); the PDF link points to this language edition.

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

Safety cap (0 = unlimited; the Actor uses TED's iteration paging, so any size works).

## Actor input object example

```json
{
  "noticeGroup": "tenders",
  "buyerCountries": [
    "ITA"
  ],
  "language": "en",
  "maxItems": 500
}
```

# Actor output Schema

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

Tenders and contract awards from TED. Every exported row is one item in the default dataset.

# 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 = {
    "buyerCountries": [
        "ITA"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("publicdata/ted-eu-public-tenders").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 = { "buyerCountries": ["ITA"] }

# Run the Actor and wait for it to finish
run = client.actor("publicdata/ted-eu-public-tenders").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 '{
  "buyerCountries": [
    "ITA"
  ]
}' |
apify call publicdata/ted-eu-public-tenders --silent --output-dataset

```

## MCP server setup

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

```

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/Nf23WvJmBtPpI7ezL/builds/mLuuc75qnUCj2Qj4v/openapi.json
