# TED EU Public Tenders Scraper - Procurement Notices API (`nexus-scrapers/ted-eu-tenders`) Actor

Scrape EU public tenders from TED (Tenders Electronic Daily), the official EU procurement journal. Search government contracts, calls for tenders, RFPs and contract award notices by CPV code, country, buyer or keyword, newest first. Official CPV labels in 24 languages. JSON, CSV, Excel. No API key.

- **URL**: https://apify.com/nexus-scrapers/ted-eu-tenders.md
- **Developed by:** [Nexus Scrapers](https://apify.com/nexus-scrapers) (community)
- **Categories:** Lead generation, Business, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 tender notices

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

## TED EU Public Tenders Scraper - Procurement Notices API

Search and export **EU public tenders and procurement notices** from **TED (Tenders Electronic Daily)**, the official EU database of public contracts, as clean, normalized JSON, CSV or Excel. Filter by keyword, buyer country, **CPV code**, notice type, publication date, submission deadline, value and buyer name. Every CPV code comes with its **official CPV 2008 label**, in any of the 24 EU languages. No API key, no proxy and no browser needed. Pay only for the results you get.

The Actor uses the official [TED Search API v3](https://docs.ted.europa.eu/api/latest/search.html) run by the Publications Office of the European Union. Each result follows the same **tender schema v1**, designed so that other procurement sources (US SAM.gov, UK Contracts Finder, Italian ANAC) can be returned in the same format.

### Who is it for

- **Bid managers and sales teams** who need a daily list of open tenders in their sector (CPV) and countries, with deadline and estimated value.
- **Consultants, analysts and market researchers** measuring public spending by buyer, country or sector, and tracking who wins contracts.
- **Suppliers and lead-generation teams** looking for contracting authorities that regularly buy what they sell.
- **AI agents and MCP users**: the dataset schema describes every field, so an agent can query EU tenders in natural language (see [API, MCP and AI agents](#api-mcp-and-ai-agents)).

### What you get

One dataset item per notice, with:

- notice id, type (contract notice, prior information, contract award, modification, ...) and procedure type
- title and short description in your preferred language (fallback: English, then original language)
- buyer name, country, city and NUTS region, plus a normalized buyer type
- all CPV codes with their official CPV 2008 label (24 EU languages), plus main CPV and its division
- estimated value and currency, number of lots
- publication date and submission deadline
- for award notices: winners (name, country), awarded value and award date
- place of performance, links to the TED page and to the HTML / PDF / XML versions

The full field reference is in [SCHEMA.md](./SCHEMA.md) and in the Actor's dataset schema (visible in the Apify UI and to AI agents using MCP).

### Use cases

- **Bid monitoring**: get new open tenders in your sector and countries every day (CPV + country + "deadline on or after today"), then schedule the Actor and send the dataset to Slack, email or a spreadsheet.
- **Market research**: measure how much a buyer, country or sector spends, which procedures it uses and how often it publishes.
- **Competitor and award tracking**: list contract award notices with the winning companies and awarded values.
- **Lead generation for suppliers**: find buyers that regularly purchase what you sell.
- **AI agents (MCP)**: the dataset schema describes every field, so an agent can query tenders in natural language through the Apify MCP server.

### Input

All filters are optional and are combined with AND.

| Field | Description |
|---|---|
| `keywords` | Free-text words or phrases (OR between items) |
| `buyerCountries` | ISO 3166-1 alpha-2 codes, e.g. `IT`, `DE` |
| `cpvCodes` | CPV codes with prefix matching: `72` or `72000000` = all IT services |
| `noticeTypes` | `contract-notice`, `prior-information`, `contract-award`, `contract-modification`, `voluntary-ex-ante`, `other` |
| `daysBack` | Published in the last N days (default 7; 0 = no limit) |
| `publicationDateFrom` / `publicationDateTo` | Explicit date range, `YYYY-MM-DD` |
| `deadlineAfter` | Submission deadline on or after this date |
| `minValue` / `maxValue` | Value range in the notice currency (no conversion) |
| `buyerName` | Word(s) contained in the buyer name |
| `maxItems` | Maximum results (default 20, maximum 15,000, newest first) |
| `preferredLanguage` | Language of titles/descriptions, e.g. `en`, `it`, `fr` |
| `cpvLabelLanguage` | Language of the CPV labels in `cpvCodes[].label`: any of the 24 EU languages, default `en` (falls back to English) |
| `expertQuery` | Advanced: a raw [TED expert query](https://docs.ted.europa.eu/api/latest/search.html). Replaces all filters above |

#### Example: by CPV code and country - open IT-services tenders in Italy and Germany

```json
{
  "noticeTypes": ["contract-notice"],
  "buyerCountries": ["IT", "DE"],
  "cpvCodes": ["72"],
  "daysBack": 14,
  "deadlineAfter": "2026-11-15",
  "maxItems": 100
}
```

#### Example: by keyword - solar tenders in France, CPV labels in French

```json
{
  "keywords": ["solar panels", "photovoltaic", "panneaux solaires"],
  "buyerCountries": ["FR"],
  "daysBack": 30,
  "cpvLabelLanguage": "fr",
  "maxItems": 50
}
```

#### Example: by date range

```json
{
  "publicationDateFrom": "2026-01-01",
  "publicationDateTo": "2026-03-31",
  "buyerCountries": ["ES"],
  "cpvCodes": ["45"],
  "maxItems": 500
}
```

#### Example: awards only - who won contracts above 1 million EUR in Italy

```json
{
  "noticeTypes": ["contract-award"],
  "buyerCountries": ["IT"],
  "daysBack": 30,
  "minValue": 1000000,
  "maxItems": 200
}
```

#### Example: advanced expert query

```json
{
  "expertQuery": "buyer-country=FRA AND classification-cpv=45* AND publication-date>=today(-30)",
  "maxItems": 50
}
```

### Output example

Trimmed real record (contract notice published on TED in October 2026). `mainCpvDivision` is the name of the 2-digit CPV division, `cpvCodes[].label` the official label of each code:

```json
{
  "schemaVersion": "1.0",
  "source": "TED",
  "sourceId": "745164-2026",
  "url": "https://ted.europa.eu/en/notice/-/detail/745164-2026",
  "documentUrls": {
    "html": "https://ted.europa.eu/it/notice/745164-2026/html",
    "pdf": "https://ted.europa.eu/it/notice/745164-2026/pdf",
    "xml": "https://ted.europa.eu/en/notice/745164-2026/xml"
  },
  "noticeType": "contract-notice",
  "noticeTypeCode": "cn-standard",
  "procedureType": "open",
  "contractNature": "services",
  "title": "GARA EUROPEA A PROCEDURA APERTA AI SENSI DELL'ART. 71 DEL D.LGS. N. 36/2023, PER L'AFFIDAMENTO PER IL SERVIZIO DI UPGRADE EVOLUTIVO DI LICENZE, SERVER, LIBRERIE E STORAGE HPE ...",
  "language": "it",
  "buyer": {
    "name": "IZSAM - Istituto Zooprofilattico Sperimentale dell Abruzzo e del Molise G. Caporale",
    "country": "IT",
    "city": "Teramo",
    "nutsCode": "ITF12",
    "buyerType": "public-body"
  },
  "cpvCodes": [{ "code": "72500000", "label": "Computer-related services" }],
  "mainCpv": "72500000",
  "mainCpvDivision": "IT services: consulting, software development, Internet and support",
  "estimatedValue": { "amount": 700000, "currency": "EUR" },
  "lots": 1,
  "publicationDate": "2026-10-27",
  "submissionDeadline": "2026-11-27T12:00:00+01:00",
  "awardInfo": null,
  "placeOfPerformance": { "country": "IT", "city": "Teramo", "nutsCode": "ITF12" },
  "scrapedAt": "2026-11-03T20:16:33+00:00"
}
```

### Pricing

Pay only for the results you get. Set **Maximum results** (and the run's maximum cost) to control spending: the Actor stops as soon as either limit is reached. Runs that find no notices return no results and charge nothing. See the Pricing tab of this Actor for the current price.

### API, MCP and AI agents

Every Apify Actor can be called over the API, and this one is also available as a tool for AI agents.

**Apify API (Python)**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nexus-scrapers/ted-eu-tenders").call(run_input={
    "cpvCodes": ["72"], "buyerCountries": ["IT"], "daysBack": 7, "maxItems": 50,
})
for tender in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(tender["publicationDate"], tender["buyer"]["name"], tender["title"])
```

**Apify API (JavaScript)**

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('nexus-scrapers/ted-eu-tenders').call({ keywords: ['cybersecurity'], maxItems: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**MCP and AI agents.** Apify exposes Actors as MCP tools through the [Apify MCP server](https://mcp.apify.com). Add `https://mcp.apify.com` (with `?actors=nexus-scrapers/ted-eu-tenders` to load this Actor directly) to Claude, ChatGPT-compatible clients, Cursor, VS Code or any MCP client, authorize with your Apify account, and ask in plain language, for example: "List open IT-services tenders in Germany with a deadline after 1 December, with CPV labels". The input and dataset schemas tell the agent every parameter and output field, and results are ready to be summarized, filtered or loaded into a spreadsheet. Also works with LangChain, LlamaIndex, CrewAI and n8n through the Apify integrations.

### FAQ

**What is a CPV code?** The Common Procurement Vocabulary (CPV) is the EU's standard classification of what is being bought (for example `72000000` = IT services, `45000000` = construction work). Filters match by prefix: `72` matches every IT-services code. The Actor adds the official label for every code and can write it in any of the 24 EU languages (`cpvLabelLanguage`).

**Do I need a TED API key?** No. The TED Search API allows anonymous access to published notices.

**Are the notices translated?** No. Titles and descriptions are written by the buyers in their own language. When a notice contains several languages, the Actor picks your preferred language, then English, then any. Buyer countries, notice types and procedure types are normalized to English codes.

**How fresh is the data?** The Actor queries TED live, so new notices appear as soon as TED publishes them; the publication date of each notice is in the output.

**Why are some fields `null`?** TED notices differ by form and age. Older notices (before the eForms rollout in 2023) often lack lots, NUTS codes, deadlines in structured form or descriptions. Award notices have no estimated value and open tenders have no `awardInfo`.

**Is the value in euros?** The value is given in the currency of the notice (`estimatedValue.currency`). No conversion is applied.

**How many results can I get?** Up to 15,000 per run. Larger exports should be split by date range.

**Can I get the full text of the tender documents?** No. The Actor returns the notice data and links to the notice in HTML, PDF and XML. Tender documents are hosted by each buyer's procurement platform.

### Data source, attribution and terms

Data comes from [TED](https://ted.europa.eu), provided by the Publications Office of the European Union. According to the [TED legal notice](https://ted.europa.eu/en/legal-notice), unless otherwise noted, procurement notices published in the Supplement to the Official Journal of the European Union can be freely reused for commercial or non-commercial purposes, under the Commission's reuse policy (Commission Decision of 12 December 2011 on the reuse of Commission documents). Please credit TED / European Union as the source and indicate if you modified the data. CPV labels come from the Common Procurement Vocabulary (CPV 2008, Regulation (EC) No 213/2008) published by the Publications Office of the European Union through [EU Vocabularies](https://op.europa.eu/en/web/eu-vocabularies/dataset/-/resource?uri=http://publications.europa.eu/resource/dataset/cpv); reuse is permitted with acknowledgement of the source (see the Publications Office [copyright notice](https://op.europa.eu/en/web/about-us/legal-notices/publications-office-of-the-european-union-copyright)), and the data is bundled here unmodified except for whitespace normalisation. This Actor is an independent tool and is not affiliated with or endorsed by the European Union. Notices may contain names of natural persons acting as contacts or sole traders; handle such data in line with GDPR.

### Limitations

- Only notices published on TED are covered; national procurement below EU thresholds is usually not on TED.
- The free-text search, buyer-name filter and value filters rely on TED's own indexing; the value filter uses the notice's total value and does not compare across currencies.
- Winner country is filled only when it can be paired reliably with the winner name.
- CPV labels follow CPV 2008; a code that is not in CPV 2008 (for example a typo in a notice) gets `label: null`.
- Submission deadline is the earliest deadline among the lots.
- The TED API occasionally returns temporary 5xx errors; the Actor retries with backoff, but a run can still fail if TED is down for several minutes.

# Actor input Schema

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

Free-text search in the notice text (title, description, buyer, ...). Several keywords are combined with OR; a keyword with spaces is matched as a phrase. Leave empty to search everything.

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

Only notices from buyers (contracting authorities) located in these countries. Leave empty for all countries.

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

Common Procurement Vocabulary codes, with prefix matching: '72' or '72000000' matches every code starting with 72 (IT services), '7221' matches 7221xxxx. Check digits such as '-4' are ignored. A notice matches if any of its CPV codes matches.

## `noticeTypes` (type: `array`):

Which kinds of notices to return. Leave empty for all types. Use 'Contract notices' for open tenders you can bid on and 'Contract award notices' to see who won.

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

Only notices published in the last N days. Ignored if 'Published from' or 'Published to' is set. Use 0 for no date limit (results are always newest first).

## `publicationDateFrom` (type: `string`):

Earliest publication date, format YYYY-MM-DD. Overrides 'last N days'.

## `publicationDateTo` (type: `string`):

Latest publication date (inclusive), format YYYY-MM-DD.

## `deadlineAfter` (type: `string`):

Only notices whose deadline for receipt of tenders is on or after this date (YYYY-MM-DD). Set it to today to get tenders that are still open for bids.

## `minValue` (type: `integer`):

Minimum estimated value (awarded value for award notices), in the notice's own currency (mostly EUR). No currency conversion is applied.

## `maxValue` (type: `integer`):

Maximum estimated value (awarded value for award notices), in the notice's own currency.

## `buyerName` (type: `string`):

Word(s) that must appear in the buyer (contracting authority) name, e.g. 'ministry' or 'comune di milano'. Matched as words, not as part of a word.

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

Maximum number of notices to return, newest first. You are charged per result, so keep this low while testing.

## `preferredLanguage` (type: `string`):

Language used for titles, descriptions and buyer names when a notice has several. Falls back to English, then to any available language. Notice texts are written by buyers in their own language and are not machine-translated.

## `cpvLabelLanguage` (type: `string`):

Language of the official CPV (Common Procurement Vocabulary) labels in cpvCodes\[].label. All 24 EU languages are available; falls back to English.

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

Advanced. A raw TED expert-search query (see the TED Developer Docs). If set, it REPLACES all the filters above (Maximum results and Preferred language still apply).

## Actor input object example

```json
{
  "keywords": [
    "solar panels",
    "photovoltaic"
  ],
  "buyerCountries": [
    "IT",
    "DE"
  ],
  "cpvCodes": [
    "72",
    "48"
  ],
  "noticeTypes": [
    "contract-notice"
  ],
  "daysBack": 7,
  "publicationDateFrom": "2026-01-01",
  "publicationDateTo": "2026-06-30",
  "deadlineAfter": "2026-12-01",
  "minValue": 100000,
  "maxValue": 5000000,
  "buyerName": "ministry",
  "maxItems": 20,
  "preferredLanguage": "en",
  "cpvLabelLanguage": "en",
  "expertQuery": "buyer-country=ITA AND classification-cpv=72* AND publication-date>=today(-30)"
}
```

# Actor output Schema

## `overview` (type: `string`):

All notices in the default dataset, opened on the Overview table (date, type, title, buyer, value, deadline, link).

## `awards` (type: `string`):

The same dataset opened on the Awards view: winners and awarded values from contract-award notices.

# 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 = {
    "noticeTypes": [
        "contract-notice"
    ],
    "daysBack": 7,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexus-scrapers/ted-eu-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 = {
    "noticeTypes": ["contract-notice"],
    "daysBack": 7,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("nexus-scrapers/ted-eu-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 '{
  "noticeTypes": [
    "contract-notice"
  ],
  "daysBack": 7,
  "maxItems": 20
}' |
apify call nexus-scrapers/ted-eu-tenders --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexus-scrapers/ted-eu-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/F1PntX0QEB0OzZUlo/builds/OzPTnP3adwvAekSOY/openapi.json
