# TED EU Public Tenders Scraper (Official API) (`ivladimir/ted-eu-tenders`) Actor

Scrape EU public tenders from the official TED API v3. Filter by keywords, CPV codes, buyer countries, notice types and publication dates. Up to 15,000 notices per run.

- **URL**: https://apify.com/ivladimir/ted-eu-tenders.md
- **Developed by:** [Владимир Иваницкий](https://apify.com/ivladimir) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## TED EU Public Tenders Scraper (Official API)

Scrape public procurement notices from **TED (Tenders Electronic Daily)**, the official EU supplement to the Official Journal. This actor queries the free, official **TED API v3** (`api.ted.europa.eu`) — no proxies, no scraping of HTML pages, no brittle selectors. Results are sorted newest first and can be filtered by keywords, CPV codes, buyer countries, notice types and publication dates.

Multilingual fields (title, description) are returned in your preferred language with automatic fallback to the original language.

### What data you get

| Field | Type | Description |
|---|---|---|
| `publicationNumber` | string | TED publication number, e.g. `755907-2026` |
| `url` | string | Human-readable notice page on ted.europa.eu |
| `title` | string | Notice title (preferred language) |
| `noticeTitle` | string | Full notice heading, usually including country and category |
| `description` | string | Notice description / subject matter |
| `buyerName` | string | Contracting authority name |
| `buyerCity` | string | Buyer city |
| `buyerCountry` | string | Buyer country (ISO 3166 alpha-3, e.g. `DEU`) |
| `publicationDate` | string | Publication date (`YYYY-MM-DD`) |
| `deadline` | string | null | Submission deadline, if published |
| `noticeType` | string | eForms notice type, e.g. `cn-standard`, `can-standard`, `pin-only` |
| `procedureType` | string | Procedure type code, e.g. `open`, `neg-w-call` |
| `contractNature` | array | `services`, `supplies`, `works` |
| `cpvCodes` | array | CPV codes (8-digit) |
| `placeOfPerformance` | array | NUTS / country codes of performance |
| `estimatedValue` | number | null | Estimated value, when published |
| `estimatedValueCurrency` | string | null | Currency of the estimated value |
| `winners` | array | null | Awarded suppliers (award notices) |
| `pdfUrl` | string | Direct PDF of the notice |
| `xmlUrl` | string | Direct eForms XML of the notice |

### Use cases

- **Lead generation** — find open tenders matching your products or services across the EU/EEA.
- **Market research** — analyse public spending by country, CPV category or buyer.
- **Competitor monitoring** — track award notices (`can-standard`) to see who wins what and at which value.
- **Tender alerts** — schedule daily runs and push new notices to Slack, email or Google Sheets.
- **Data pipelines** — feed structured procurement data into BI tools, warehouses or ML models.
- **Consultancies & bid writers** — build shortlists of relevant opportunities for clients.

### How to use

1. Open the actor in Apify Console and go to the **Input** tab.
2. Add one or more **keywords** (any of them matches), e.g. `software`, `cleaning`, `medical equipment`.
3. Optionally narrow by **buyer countries** (ISO alpha-3: `DEU`, `FRA`, `POL`…), **CPV codes** (8-digit, exact match) and **notice types** (`cn-standard`, `can-standard`, `pin-only`…).
4. Set the **publication date range** — defaults to the last 7 days. Enable **Only active notices** to skip expired deadlines.
5. Choose the **preferred language** for multilingual fields (default `eng`).
6. Set **Max notices** (up to 15,000 per run) and click **Start**.
7. Download results from the **Dataset** tab as JSON, CSV, Excel or via the API.

### Input example

```json
{
  "keywords": ["software"],
  "buyerCountries": ["DEU", "POL"],
  "cpvCodes": ["72000000"],
  "noticeTypes": ["cn-standard"],
  "publishedSince": "2026-10-23",
  "publishedUntil": "2026-10-30",
  "onlyActive": true,
  "language": "eng",
  "customQuery": "procedure-type=open",
  "maxItems": 200
}
```

### Output example

```json
{
  "publicationNumber": "755907-2026",
  "url": "https://ted.europa.eu/en/notice/-/detail/755907-2026",
  "title": "Neubau Verwaltungsgebäude der Verbandsgemeindewerke in Bernkastel-Kues / Andel: Los 3 - Leistungen der Tragwerksplanung",
  "noticeTitle": "Germany – Engineering services – Neubau Verwaltungsgebäude der Verbandsgemeindewerke in Bernkastel-Kues / Andel: Los 3 - Leistungen der Tragwerksplanung",
  "description": "Gegenstand der Planungsaufgabe ist der Neubau eines Verwaltungsgebäudes der Verbandsgemeindewerke in Bernkastel-Kues im Stadtteil Andel einschließlich der zugehörigen Freianlagen und der Einbindung in den bestehenden Betriebsstandort auf dem Grundstück \"Moselbahnstraße 14 in 54470 Bernkastel-Kues / ",
  "buyerName": "Verbandsgemeinde Bernkastel-Kues",
  "buyerCity": "Bernkastel-Kues",
  "buyerCountry": "DEU",
  "publicationDate": "2026-10-30",
  "deadline": null,
  "noticeType": "cn-standard",
  "procedureType": "neg-w-call",
  "contractNature": ["services"],
  "cpvCodes": ["71300000", "71327000"],
  "placeOfPerformance": ["DEB22", "DEU"],
  "estimatedValue": null,
  "estimatedValueCurrency": null,
  "winners": null,
  "pdfUrl": "https://ted.europa.eu/en/notice/755907-2026/pdf",
  "xmlUrl": "https://ted.europa.eu/en/notice/755907-2026/xml"
}
```

### Pricing

This actor uses **pay-per-result** pricing: **$2 per 1,000 results** (see the **Pricing** tab for whether Apify platform usage is included).

Cost examples:

| Notices | Cost |
|---|---|
| 200 | $0.40 |
| 1,000 | $2.00 |
| 5,000 | $10.00 |
| 15,000 (max per run) | $30.00 |

You are only charged for notices actually saved to the dataset — a run that returns fewer results costs proportionally less.

### FAQ

**Is this legal?**
Yes. TED is the official EU publication of public procurement notices, and this actor uses the official, free TED API v3. Only publicly available procurement data is collected. The actor does not bypass authentication or paywalls, and it accesses the API in a polite, rate-limited manner.

**Do I need an API key or proxy?**
No. The TED API is free and open, so no API key is required and no proxy is used.

**How far back can I search?**
Set `publishedSince` to any date supported by the TED API. If left empty, it defaults to 7 days ago. Use `publishedUntil` to close the range.

**What does `onlyActive` do?**
When enabled, notices whose submission deadline has already passed are excluded, so you only get opportunities you can still bid on.

**Why are some fields `null`?**
TED notices vary by type and completeness. Deadlines, estimated values and winners are only present when the buyer published them — for example, winners appear mainly on award notices (`can-standard`).

**What happens if my preferred language is missing?**
Multilingual fields fall back to the original language of the notice, so you always get a value when one exists.

**What is `customQuery` for?**
It lets you append an extra TED expert-search clause (e.g. `procedure-type=open`), which is ANDed with your other filters.

### Integrations

- **API** — run the actor and fetch the dataset programmatically via the Apify API.
- **Webhooks** — trigger a webhook on run success to notify your own service.
- **Google Sheets** — export the dataset directly to a spreadsheet.
- **Make / Zapier** — connect Apify to hundreds of apps and build automated tender-alert workflows.
- **Scheduling** — set a daily or weekly schedule to collect new notices automatically.

### 🇺🇦 Коротко українською

Цей актор збирає публічні тендери ЄС із офіційного сервісу TED через безкоштовний API v3 — без проксі та без парсингу HTML. Можна фільтрувати за ключовими словами, кодами CPV, країнами замовників, типами оголошень і датами публікації. За один запуск обробляється до 15 000 оголошень, результати сортуються від найновіших. Оплата — за результат: $2 за 1 000 оголошень (див. вкладку Pricing). Дані експортуються в JSON, CSV чи Excel, а запуск можна поставити на розклад.

# Actor input Schema

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

Full-text search terms (any of them matches), e.g. software, cleaning, medical equipment.

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

e.g. DEU, FRA, POL, ITA, ESP. Empty = all EU/EEA.

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

8-digit CPV codes, e.g. 72000000 (IT services), 45000000 (construction). Exact code match.

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

eForms notice types, e.g. cn-standard (contract notice), can-standard (award), pin-only. Empty = all.

## `publishedSince` (type: `string`):

Default: 7 days ago.

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

Optional.

## `onlyActive` (type: `boolean`):

Only notices whose deadline has not passed.

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

Three-letter code for multilingual fields (eng, deu, fra, pol...). Falls back to the original language.

## `customQuery` (type: `string`):

Extra TED expert-search clause, ANDed with the filters, e.g. procedure-type=open.

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

Up to 15,000 per run.

## Actor input object example

```json
{
  "keywords": [
    "software"
  ],
  "buyerCountries": [
    "DEU",
    "POL"
  ],
  "onlyActive": false,
  "language": "eng",
  "maxItems": 200
}
```

# Actor output Schema

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

All scraped items 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 = {
    "keywords": [
        "software"
    ],
    "buyerCountries": [
        "DEU",
        "POL"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ivladimir/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 = {
    "keywords": ["software"],
    "buyerCountries": [
        "DEU",
        "POL",
    ],
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ivladimir/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/N0KdAGQBkwwyYWaUs/builds/BKNCO4Z25bd0lq3Z6/openapi.json
