# EU Tenders Scraper - TED Public Procurement Notices (`scoutdesk/eu-ted-tenders-scraper`) Actor

Get EU public tenders, contract awards and prior information notices from TED (Tenders Electronic Daily) via the official API. Filter by country, CPV, NUTS region, keyword, buyer and EUR value. Winners, deadlines, monitor mode for new-only alerts. No API key.

- **URL**: https://apify.com/scoutdesk/eu-ted-tenders-scraper.md
- **Developed by:** [Scout Desk](https://apify.com/scoutdesk) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 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

## EU Tenders Scraper: TED Public Procurement Notices API

Get **EU public tenders, contract awards and procurement pipeline notices** from **TED (Tenders Electronic Daily)**, the official EU procurement journal, as clean, flat rows. Filter by **country, CPV code, NUTS region, keyword, buyer and contract value in EUR**, see **who won what for how much**, and schedule it as a **daily new-tender alert feed**. It uses the official TED API, so you need no API key, proxies or browser. You pay only for the notices you keep.

### What does EU Tenders Scraper do?

Public buyers in the 27 EU member states, the EEA, Switzerland and several candidate countries must publish above-threshold procurement notices in TED, the Supplement to the Official Journal of the EU. That's **3,000+ notices every working day**. This Actor queries the **official TED Search API v3** run by the Publications Office of the EU and turns its eForms data into **one analysis-ready row per notice**:

- **Open tenders** (contract notices and calls for competition), with submission deadlines and links to the e-tendering portal
- **Planning notices** (prior information and market consultations), which show opportunities before the tender starts
- **Contract awards** (winning suppliers, their country and size, and award values)
- **Contract modifications**

Filtering runs **server-side in TED's own search engine**, so even a narrow search over a whole year finishes in seconds.

### Why use it?

- 🎯 **Find opportunities early.** Run it each morning with your CPV codes and countries, and get only the notices you haven't seen.
- 🌍 **Built for cross-border bidders.** Every row has an **English headline** ("Germany – Software package and information systems – …") and an **EUR value** converted with the ECB reference rate, so you can compare Polish zloty and Swedish krona notices side by side.
- 🏆 **Win/loss and market intelligence.** Award notices show who won, with supplier country, SME size and award value.
- 🧹 **Less noise.** Republished procedures are collapsed to the newest notice, and keywords are matched against the title and description rather than legal boilerplate.
- ⚖️ **Legally clean.** TED notices may be reused for commercial or non-commercial purposes under the European Commission's reuse policy (Decision 2011/833/EU).

**Who uses it:** bid and proposal teams, SME suppliers selling to the public sector across Europe, consultancies and tender-alert services, sales and business development teams, market researchers, journalists and procurement analysts.

### What data can you extract?

| Field | Example |
|---|---|
| Notice ID, stage, notice type, procedure | 696492-2026, tender, cn-standard, open |
| Title (original) and English headline | "Commvault" / "Austria – Software package and information systems – Commvault" |
| Buyer name, country, city, website, type | Bundesbeschaffung GmbH, AUT, Wien |
| CPV codes, main CPV and its English description | 48000000 "Software package and information systems" |
| Place of performance: countries, NUTS codes, towns | AUT, ATZZZ |
| Estimated value, awarded value, currency, **value in EUR** | 21000000 EUR |
| Submission deadline(s), request-to-participate deadline | 2026-11-09T11:00:00+02:00 |
| Lots, duration, contract start/end, framework flag | 1 lot, 48 months, framework |
| SME suitability | true |
| Winners: name, country, size; award decision date | BECKMAN COULTER, FRA, medium |
| Links: TED notice page, PDF, e-tendering submission and documents | ted.europa.eu/…, vergabeportal.at/… |
| Procedure ID (links tenders to their later awards) | 08712e18-… |

### How to use it

1. Click **Try for free**.
2. Choose **CPV codes** and/or **keywords**, and optionally **countries**, **NUTS regions**, **notice types** and a **value range in EUR**.
3. Set **Days back** (default 7) and **Max results**.
4. Click **Start**, then download the results as JSON, CSV, Excel or HTML, or use the API.

#### Daily alert feed (monitor mode)

Turn on **Monitor mode: only new notices** and give your search a **Monitor key** (e.g. `dach-it`). Then create an Apify **Schedule** (e.g. every weekday at 08:00 CET). Each run returns only notices you haven't seen before. Send them to email, Slack, Google Sheets, HubSpot, Zapier or Make with Apify integrations.

### Input examples

IT tenders in Germany, Austria and Switzerland (main CPV only):

```json
{ "cpvCodes": ["72", "48"], "cpvMatch": "main", "countries": ["DE", "Austria", "CHE"], "noticeStages": ["tender"], "daysBack": 7, "maxResults": 30 }
```

Medical-equipment contract awards in France over €1m:

```json
{ "cpvCodes": ["33"], "countries": ["France"], "noticeStages": ["award"], "minValueEur": 1000000, "daysBack": 14, "maxResults": 25 }
```

Cybersecurity tenders and market consultations in the Nordics, as a daily monitor (note the local-language keywords):

```json
{ "keywords": ["cyber", "security operations", "SOC", "informationssäkerhet", "tietoturva"], "countries": ["SE", "DK", "FI", "NO"],
  "noticeStages": ["tender", "planning"], "daysBack": 3, "onlyNewSinceLastRun": true, "monitorKey": "nordic-cyber" }
```

Construction work performed in Berlin (NUTS DE3), worth €500k or more:

```json
{ "cpvCodes": ["45"], "nutsCodes": ["DE3"], "noticeStages": ["tender", "planning"], "daysBack": 30, "minValueEur": 500000 }
```

### Output example

One notice from a real run on 8 Oct 2026 (selected fields, long text shortened):

```json
{
  "noticeId": "696492-2026",
  "stage": "tender",
  "noticeType": "cn-standard",
  "procedureType": "open",
  "contractNature": "supplies",
  "title": "Commvault",
  "titleEnglish": "Austria – Software package and information systems – Commvault",
  "description": "Gegenstand dieser Rahmenvereinbarung ist die Lieferung von Softwarelizenzen, Subscription, Wartungen, Produkten und damit verbundener Dienstleistungen…",
  "language": "DEU",
  "buyerName": "Auftraggeber sind die Republik Österreich (Bund), die Bundesbeschaffun…",
  "buyerCountry": "AUT",
  "buyerCity": "Wien",
  "buyerWebsite": "https://www.bbg.gv.at",
  "cpvCodes": [
    "48000000"
  ],
  "mainCpv": "48000000",
  "mainCpvDescription": "Software package and information systems",
  "performanceNuts": [
    "ATZZZ"
  ],
  "estimatedValue": 21000000,
  "estimatedValueCurrency": "EUR",
  "valueEur": 21000000,
  "tenderDeadline": "2026-11-09T11:00:00+02:00",
  "durationMonths": 48,
  "contractStart": "2027-03-15",
  "suitableForSme": true,
  "frameworkAgreement": true,
  "submissionUrl": "https://bbg.vergabeportal.at/Detail/257251",
  "noticeUrl": "https://ted.europa.eu/en/notice/-/detail/696492-2026",
  "pdfUrl": "https://ted.europa.eu/en/notice/696492-2026/pdf",
  "publishedDate": "2026-10-08",
  "procedureId": "08712e18-f9d7-42c9-88e0-54a528c66fce"
}
```

Award rows also include `awardedSuppliers` (e.g. `[{"name": "BECKMAN COULTER", "country": "FRA", "size": "medium"}]`), `awardValue` and `awardDecisionDate`.

### How much does it cost to scrape EU tenders?

This Actor uses **pay-per-result** pricing. You pay a small fixed price for each notice saved to your dataset, and **notices filtered out by your criteria are free**. There's no separate charge for compute. A daily sector monitor typically returns 5–50 new notices, which costs cents per day. You can cap spending per run with Apify's *maximum cost per run* setting, and the Actor stops cleanly at your limit.

### Tips

- **Use CPV codes for cross-language searches.** Notices are written in the buyer's language, so the keyword "software" won't find a French "logiciel" tender. CPV codes such as `72` (IT services), `48` (software), `45` (construction), `33` (medical), `79` (business services) and `90` (environmental services) work in every language. Combine them with local-language keywords when you need precision.
- **CPV applies to:** "Any CPV code" also matches secondary codes. Choose **Main CPV code only** for precise results.
- **Keyword scope:** the default, *Title + description*, is precise. *Entire notice text* also matches legal boilerplate, so expect noise. Short ALL-CAPS keywords such as `SOC` or `IT` match whole words only.
- **Countries** accept names (Germany), ISO-2 (DE) or ISO-3 (DEU) codes, and match the buyer's country by default. Switch *Country applies to* to *Place of performance* to find contracts delivered in a country.
- **Values:** many buyers (especially in Germany) don't publish an estimated value. When you set a minimum or maximum value, notices without one are excluded.
- **Power users:** add any TED expert-search condition in *TED expert query*, for example `procedure-type=open` or `total-value>=1000000`.
- **Run time:** typically 5–30 seconds, because TED filters server-side.

### FAQ

**Is it legal to scrape TED?** Yes. The Actor uses TED's official public Search API, which is designed for reusers and needs no key. The Commission's reuse policy permits commercial and non-commercial reuse of the notices. Respect any third-party rights mentioned in individual notices.

**What about personal data / GDPR?** Buyer contact emails are **off by default** because they can name individuals. If you turn them on, you're responsible for GDPR-compliant use.

**How fresh is the data?** It's live. Each run queries TED directly. TED publishes new notices every working day (Monday–Friday).

**Does it cover national below-threshold tenders?** Only those that buyers choose to publish on TED. National portals (e.g. Germany's service.bund.de or France's BOAMP) also carry many smaller tenders.

**UK tenders?** Since Brexit, UK notices are published on Find a Tender and Contracts Finder, not TED. Use our companion Actor, [UK Government Tenders Scraper (Find a Tender & Contracts Finder)](https://apify.com/scoutdesk/uk-public-tenders-scraper).

### Other public procurement data

- 🇪🇺 **EU Tenders Scraper (TED)** (this Actor).
- 🇬🇧 **[UK Government Tenders Scraper](https://apify.com/scoutdesk/uk-public-tenders-scraper)**: Find a Tender and Contracts Finder, with tenders, pipeline notices, awards and monitor mode.

### Support

Open an issue on the Actor's **Issues** tab. We monitor runs daily and aim to fix problems within 48 hours.

***

*Source: TED – Tenders Electronic Daily, © European Union, https://ted.europa.eu. Reuse is authorised under Commission Decision 2011/833/EU. Exchange rates: European Central Bank euro foreign exchange reference rates. This Actor is not affiliated with or endorsed by the European Union or the Publications Office of the EU.*

# Actor input Schema

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

Words or phrases to look for (any of them by default). TED notices are in the buyer's own language, so add local-language terms too (e.g. 'software', 'Software', 'logiciel', 'oprogramowanie') or use CPV codes, which work across all languages. Leave empty for all notices.

## `keywordMatch` (type: `string`):

Return notices containing any of the keywords, or only those containing all of them.

## `keywordScope` (type: `string`):

Title + description matches the notice title, lot titles and procedure description. Title only matches TED's notice title, which also contains the English CPV description (e.g. 'Germany – Software package and information systems – ...'). Entire notice text also matches boilerplate sections such as legal clauses, so expect noise.

## `excludeKeywords` (type: `array`):

Drop notices whose title or description contains any of these words.

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

Common Procurement Vocabulary codes or prefixes. '72' = all IT services, '48' = software packages, '45' = construction, '33' = medical equipment. Full codes like 72000000 or 72000000-5 also work.

## `cpvMatch` (type: `string`):

Match CPV codes anywhere in the notice (including secondary codes), or only the procedure's main CPV code.

## `noticeStages` (type: `array`):

Which kinds of notice to return.

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

Countries by name (Germany), ISO-2 (DE) or ISO-3 (DEU) code. EU, EEA and other TED countries. Leave empty for all.

## `countryMatch` (type: `string`):

Match the buyer's country, or the country where the contract is performed.

## `nutsCodes` (type: `array`):

Place-of-performance NUTS codes or prefixes, e.g. 'DE3' (Berlin), 'FR1' (Ile-de-France), 'NL32', 'ES51'.

## `buyerNameContains` (type: `array`):

Only notices from buyers whose name contains any of these words (e.g. 'Stadt', 'hospital', 'Universit').

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

How many days of publications to search, counting back from today. TED publishes on weekdays. Ignored when 'Published from' is set.

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

Optional start date (YYYY-MM-DD). Overrides 'Days back'.

## `publishedTo` (type: `string`):

Optional end date (YYYY-MM-DD). Defaults to today.

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

Drop calls for competition whose submission deadline has already passed.

## `minValueEur` (type: `integer`):

Only notices with an estimated or awarded value at or above this amount. Other currencies are converted with the ECB euro reference rates. Notices without a published value are excluded when set.

## `maxValueEur` (type: `integer`):

Only notices with a value at or below this amount (EUR, converted as above).

## `smeSuitableOnly` (type: `boolean`):

Only notices where the buyer marked at least one lot as suitable for SMEs.

## `collapseRepublished` (type: `boolean`):

Buyers often republish the same procedure (corrections, re-launches). Keep only the newest notice per procedure and stage. Turn off to get every notice.

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

Maximum number of notices to save (newest first). You are charged per saved notice.

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

Remember notices returned in previous runs (per 'Monitor key') and return only ones you have not seen. Schedule the Actor daily for a new-tender alert feed.

## `monitorKey` (type: `string`):

Name of this saved search for monitor mode. Use a different key for each search you schedule.

## `includeBuyerContacts` (type: `boolean`):

Add the buyer's published contact email. It can name a person; you are responsible for GDPR-compliant use.

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

Optional extra condition in TED's expert search syntax, combined with AND, e.g. procedure-type=open or total-value>=1000000. See the TED help pages.

## Actor input object example

```json
{
  "keywords": [
    "software",
    "cloud"
  ],
  "keywordMatch": "any",
  "keywordScope": "titleAndDescription",
  "excludeKeywords": [],
  "cpvCodes": [],
  "cpvMatch": "any",
  "noticeStages": [
    "tender"
  ],
  "countries": [],
  "countryMatch": "buyer",
  "nutsCodes": [],
  "buyerNameContains": [],
  "daysBack": 7,
  "onlyOpen": true,
  "smeSuitableOnly": false,
  "collapseRepublished": true,
  "maxResults": 20,
  "onlyNewSinceLastRun": false,
  "monitorKey": "default",
  "includeBuyerContacts": false
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

# 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 = {
    "keywords": [
        "software",
        "cloud"
    ],
    "daysBack": 7,
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("scoutdesk/eu-ted-tenders-scraper").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 = {
    "keywords": [
        "software",
        "cloud",
    ],
    "daysBack": 7,
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("scoutdesk/eu-ted-tenders-scraper").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 '{
  "keywords": [
    "software",
    "cloud"
  ],
  "daysBack": 7,
  "maxResults": 20
}' |
apify call scoutdesk/eu-ted-tenders-scraper --silent --output-dataset

```

## MCP server setup

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

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/HnqXLgRNHf4eQxza7/builds/W9fz0LnwoFQUDkJEt/openapi.json
