# EU Public Tenders Scraper (TED) + AI Bid Summaries (`data-drip/eu-tenders-ted-ai`) Actor

Search EU public procurement tenders from TED (Tenders Electronic Daily) via the official API: buyer, country, CPV, estimated value, deadline, documents and submission links. Optional AI adds English summaries, requirements and a bid-fit score.

- **URL**: https://apify.com/data-drip/eu-tenders-ted-ai.md
- **Developed by:** [Ibraheem Ganayim](https://apify.com/data-drip) (community)
- **Categories:** Lead generation, AI, Business
- **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 notice scrapeds

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 Scraper (TED) + AI Bid Summaries

**TED Tenders Scraper at a glance:** data from the official TED Search API v3 of the EU Publications Office · no login, no browser, no proxies · **$3 per 1,000 tender notices** · optional AI with your own key · JSON, CSV, Excel export, API and MCP ready

### What does the TED Tenders Scraper do?

Search **EU public procurement tenders** published on **TED (Tenders Electronic Daily)**, the official journal for public contracts in the EU, EEA and partner countries. Filter by **keyword, buyer country, CPV sector code, notice type and dates**, and get one clean row per notice: **title, buyer, country, city, CPV codes, estimated value, submission deadline, procedure type, framework flag, contract duration, documents link and e-submission link**. Turn on the optional **AI bid summaries** to get an **English summary of foreign-language tenders, key requirements, red flags and a 0-100 bid-fit score** against your own company profile.

The Actor uses the **official TED Search API v3** (`api.ted.europa.eu`), which the EU Publications Office provides for anonymous, programmatic reuse of notices. No browser, no login, no proxies.

### Why this TED tender scraper?

- **All of TED in one search**: thousands of new notices every publishing day across 30+ countries and 24 languages
- **Bid-ready filters**: keywords in any language, buyer countries (`ES`, `DE`, `FR`...), CPV sectors (parent codes include children), open calls only, awards only, publication dates
- **Only open tenders by default**: notices whose submission deadline has not passed yet
- **Clean, flat schema**: original title plus TED's translated title, first buyer, deadline as a date, value and currency, direct links to documents and e-submission portals
- **AI bid triage** (optional, your own OpenAI/OpenRouter key): English summary, sector, requirements, red flags and a fit score for your company
- **Privacy-first**: notice-level data about public buyers only; no contact persons, e-mails, phone numbers or winner details

### Use cases

- **Daily tender alerts** for your sector and countries (schedule the Actor and send new rows to Slack, e-mail or a CRM)
- **Bid/no-bid triage** with AI fit scores instead of reading 40 notices in 10 languages
- **Public sector sales pipelines** for IT, consulting, construction, healthcare and facility services companies
- **Market sizing**: estimated contract values by CPV code, country and buyer
- **Competitor and award research** with contract award notices (values, dates, buyers)
- **AI agents and RAG** over procurement data via the Apify API or MCP

### How to use the TED Tenders Scraper

1. Click **Try for free** (or **Start**) on this page and sign in to Apify.
2. Enter keywords and/or buyer countries (`ES`, `DE`, `FR`...) and CPV sector codes.
3. Choose open calls for tender, contract awards or all notices, and a publication date range.
4. Optionally enable AI bid summaries, describe your company for fit scores, and paste your OpenAI or OpenRouter key.
5. Click **Start**, then download results as JSON, CSV or Excel, or fetch them via the API.

### Input

| Field | Description |
|---|---|
| `keywords` | Full-text search in any language. Every word must match; use quotes for phrases, e.g. `"machine learning"` |
| `countries` | Buyer countries as ISO codes, 2 or 3 letters (`ES`, `ESP`, `DE`, `FR`...) |
| `cpvCodes` | CPV sector codes; parent codes include children (`72000000` = all IT services) |
| `noticeType` | `competition` (calls for tender, default), `result` (contract awards), `planning` or `all` |
| `onlyOpen` | Only calls whose submission deadline is today or later (default `true`) |
| `publishedFrom` / `publishedTo` | Publication date range (YYYY-MM-DD). Defaults to the last 30 days |
| `expertQuery` | Optional raw TED expert-search syntax, AND-ed with the filters |
| `language` | Language for translated titles and buyer names (default `eng`) |
| `maxResults` | Maximum notices, newest first (default 100) |
| `enableAi`, `companyProfile`, `llmProvider`, `llmApiKey`, `llmModel` | Optional AI bid summaries and fit scoring with your own key |

```json
{ "keywords": "software", "countries": ["ES", "PT"], "noticeType": "competition", "onlyOpen": true, "maxResults": 100 }
```

### Output example

One row per tender notice, straight from the official TED Search API v3 of the EU Publications Office:

```json
{
  "noticeId": "755824-2026",
  "title": "Licencias Liferay, soporte y mantenimiento",
  "titleTranslated": "Spain – Software package and information systems – Licencias Liferay, soporte y mantenimiento",
  "originalLanguage": "spa",
  "description": "Licencias Liferay, soporte y mantenimiento",
  "formType": "competition",
  "noticeType": "cn-standard",
  "procedureType": "open",
  "contractNature": "supplies",
  "buyerName": "IZFE - Sociedad Foral de Servicios Informáticos - IZFE - Sociedad Foral de Servicios Informáticos",
  "buyerCount": 1,
  "buyerCountry": "ESP",
  "buyerCountries": [
    "ESP"
  ],
  "buyerCity": "Donostia / San Sebastián",
  "placeOfPerformance": [
    "ES212",
    "ESP"
  ],
  "cpvCodes": [
    "48000000",
    "72610000",
    "72267000"
  ],
  "publicationDate": "2026-10-30",
  "submissionDeadline": "2026-11-30",
  "estimatedValue": 298500,
  "estimatedValueCurrency": "EUR",
  "awardedValue": null,
  "awardedValueCurrency": null,
  "frameworkAgreement": false,
  "durationValue": null,
  "durationUnit": null,
  "documentsUrl": "https://www.contratacion.euskadi.eus",
  "submissionUrl": "https://www.contratacion.euskadi.eus/KPELicitacion",
  "noticeUrl": "https://ted.europa.eu/en/notice/-/detail/755824-2026",
  "pdfUrl": "https://ted.europa.eu/en/notice/755824-2026/pdf",
  "ai": {
    "titleEn": "Liferay licences, support and maintenance",
    "summary": "IZFE, the IT company of the Gipuzkoa provincial government, is buying Liferay DXP licences plus support and maintenance. The contract covers subscription renewal and vendor support for its web platforms.",
    "sector": "Software licensing",
    "keyRequirements": [
      "Liferay DXP subscription licences",
      "Vendor support and maintenance",
      "Basque public sector buyer",
      "Electronic submission"
    ],
    "relevanceScore": 82,
    "relevanceReason": "Matches a Spanish Liferay/Java integrator selling licences and support.",
    "redFlags": []
  },
  "scrapedAt": "2026-11-01T11:40:12.115Z"
}
```

The `ai` object only appears when AI summaries are enabled with a key (values shown are illustrative; all other fields come from a real run).

### How much does it cost?

This Actor uses **pay per event** pricing: you pay only for results saved to your dataset, with no monthly fee. Apify platform compute is included.

| Event | Price |
|---|---|
| Tender notice scraped | **$0.003** per notice ($3 per 1,000) |
| AI bid summary | **$0.006** per notice (plus your own LLM tokens) |

**Examples**

- 1,000 tender notices: **$3**
- 10,000 tender notices: **$30**
- 1,000 tender notices with AI: **$9** plus your LLM tokens (typically cents with `gpt-4o-mini`)

Apify's Free plan includes $5 of monthly usage, enough for about **1,666 tender notices** without AI. Set **Maximum cost per run** in the run options to cap spend; the Actor stops cleanly at the limit.

### Use it via API, Python, n8n, Make or AI agents

Run the Actor and get results in one call (replace `<APIFY_TOKEN>` with your token):

```bash
curl -X POST "https://api.apify.com/v2/acts/data-drip~eu-tenders-ted-ai/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H 'Content-Type: application/json' \
  -d '{"keywords": "software", "countries": ["ES", "PT"], "cpvCodes": ["72000000"], "maxResults": 100}'
```

```python
from apify_client import ApifyClient

client = ApifyClient('<APIFY_TOKEN>')
run = client.actor('data-drip/eu-tenders-ted-ai').call(run_input={"keywords": "software", "countries": ["ES", "PT"], "cpvCodes": ["72000000"], "maxResults": 100})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

- **Schedules**: run it hourly, daily or weekly from Apify Schedules.
- **Integrations**: send results to Google Sheets, Slack, Zapier, Make, n8n or a webhook.
- **AI agents (MCP)**: add `data-drip/eu-tenders-ted-ai` as a tool in the Apify MCP server (`https://mcp.apify.com`) for Claude, Cursor and other MCP clients.

### Limitations

- Covers notices published on TED (above-threshold EU procurement); smaller national-only tenders are not on TED.
- Contact persons, e-mails and winner details are deliberately excluded.
- Estimated values are only present when the buyer published one.

### FAQ

**Is it allowed?** Yes. TED notices are official public information published by the EU Publications Office, and the TED Search API is offered for anonymous programmatic access and reuse. The Actor sends modest, sequential requests.

**Why are contact persons, e-mails and winners not included?** We keep the output free of personal data. Each row links to the full TED notice and the buyer's documents portal, where you find every detail needed to bid.

**Which countries are covered?** Every country that publishes on TED: all 27 EU member states, plus EEA and other countries such as Norway, Iceland, Switzerland and some candidate countries, along with EU institutions.

**What are CPV codes?** The Common Procurement Vocabulary classifies what is bought. `72000000` covers IT services, `48000000` software packages, `45000000` construction, `79000000` business services, `33000000` medical equipment. Parent codes automatically include their sub-codes.

**Why is the estimated value empty sometimes?** Buyers are not required to publish a value. When they do, it is taken from the procedure, or summed over its lots.

**Do I need an AI key?** No. Without a key the Actor is a fast tender scraper and you pay only for notices. To enable AI, paste your own OpenAI or OpenRouter key into **LLM API key** (stored as an encrypted secret) and optionally describe your company in **Your company profile** to get fit scores. LLM tokens are billed by your provider, not by us.

**Can I schedule it?** Yes. Use Apify Schedules (for example daily) and connect the dataset to Google Sheets, Slack or a webhook to get only fresh tender notices.

**How do I get help or request a feature?** Open an issue on the Actor's **Issues** tab.

***

**Related searches:** ted scraper, eu tenders, public procurement data, government tenders, tenders electronic daily api, cpv codes, bid management, public sector sales, tender alerts, licitaciones publicas.

# Actor input Schema

## `keywords` (type: `string`):

Full-text search across the whole notice in any EU language. Every word must match; wrap phrases in quotes, e.g. "machine learning". Leave empty to filter only by country, CPV and dates.

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

Optional. ISO country codes of the contracting authority, 2 or 3 letters (ES or ESP, DE, FR, IT, NL...). Several countries are OR-ed.

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

Optional. Common Procurement Vocabulary codes; parent codes include all children (72000000 = all IT services, 48000000 = software packages, 45000000 = construction). Several codes are OR-ed.

## `noticeType` (type: `string`):

Which kind of TED notices to return.

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

For calls for tender, keep only notices whose submission deadline is today or later.

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

Only notices published on or after this date (YYYY-MM-DD). Defaults to the last 30 days.

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

Only notices published on or before this date.

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

Raw TED expert-search syntax, AND-ed with the filters above, e.g. procedure-type=open AND contract-nature=services.

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

Language for the translated title, buyer name and city when TED provides it.

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

Maximum number of notices to return (newest first).

## `enableAi` (type: `boolean`):

Add an English summary, English title, sector, key requirements and red flags for each notice, plus a 0-100 fit score if you describe your company below. Requires your own OpenAI or OpenRouter key.

## `companyProfile` (type: `string`):

Optional. One or two sentences on what you sell and where, e.g. 'Spanish cloud consultancy, Azure and data platforms, projects EUR 50k-2M'. The AI scores each tender's fit against it.

## `llmProvider` (type: `string`):

Which API your key belongs to.

## `llmApiKey` (type: `string`):

Your OpenAI or OpenRouter API key. Stored encrypted.

## `llmModel` (type: `string`):

Defaults to gpt-4o-mini (OpenAI) or openai/gpt-4o-mini (OpenRouter).

## Actor input object example

```json
{
  "keywords": "software",
  "countries": [
    "ES"
  ],
  "noticeType": "competition",
  "onlyOpen": true,
  "language": "eng",
  "maxResults": 100,
  "enableAi": false,
  "llmProvider": "openai"
}
```

# Actor output Schema

## `tenders` (type: `string`):

No description

## `aiSummaries` (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",
    "countries": [
        "ES"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("data-drip/eu-tenders-ted-ai").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",
    "countries": ["ES"],
}

# Run the Actor and wait for it to finish
run = client.actor("data-drip/eu-tenders-ted-ai").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",
  "countries": [
    "ES"
  ]
}' |
apify call data-drip/eu-tenders-ted-ai --silent --output-dataset

```

## MCP server setup

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

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/zAEVFprG0vl1QWuSi/builds/BOxd7qeMKuTTdSLfy/openapi.json
