# EU & Spain Public Tenders Scraper – TED API (`metropolitan_saint/eu-public-tenders-scraper`) Actor

Extract real-time public procurement tenders and government contracts across Spain and the EU (licitaciones públicas) from official TED open data with CPV filters and MCP AI integration.

- **URL**: https://apify.com/metropolitan_saint/eu-public-tenders-scraper.md
- **Developed by:** [Leonardo Martins Da Silva](https://apify.com/metropolitan_saint) (community)
- **Categories:** Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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 & Spain Public Tenders Scraper – TED Procurement API (CPV Filters)

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue.svg)](https://apify.com)
[![Open Data](https://img.shields.io/badge/Data-Official%20EU%20TED%20v3-green.svg)](https://ted.europa.eu)
[![Pricing](https://img.shields.io/badge/Price-%244.00%20%2F%201K%20results-orange.svg)](#pricing--monetization)
[![MCP Compatible](https://img.shields.io/badge/AI-MCP%20Server%20Ready-purple.svg)](#ai-agents--mcp-server-integration)

Extract, monitor, and automate real-time **public tenders, government contracts, RFPs, and public procurement opportunities (licitaciones públicas)** across Spain and the 27 European Union member states. Powered by the official EU **Tenders Electronic Daily (TED v3)** open data architecture.

***

### 🎯 Why This Scraper?

Every day, public administrations, city halls, regional ministries, and European agencies publish millions of euros in lucrative tenders for software development, IT maintenance, infrastructure, medical supplies, and consulting.

Traditional HTML scrapers break constantly due to Cloudflare firewalls, require costly residential proxies, and suffer from CAPTCHAs. This Actor eliminates those issues completely:

- ⚡ **Zero Residential Proxy Costs:** Directly queries official EU high-availability open data infrastructure. 0% ban rate, 100% compliant.
- 🔄 **Incremental Monitoring Mode (`onlyNew`):** Automatically remembers previously extracted tenders across scheduled runs (e.g. daily/hourly cron) and only delivers brand-new notices without duplicate charges.
- 💶 **Filtered by Budget Threshold:** Exclude micro-contracts and focus solely on high-margin tenders (e.g., minimum €50,000 or €100,000+).
- 🏷️ **Standardized CPV Taxonomy:** Filter by official Common Procurement Vocabulary (e.g., `72000000` for IT services, `45000000` for Construction, `33000000` for Medical Equipment).
- 🔗 **Direct Official Document Links:** Instant direct links to the official notice HTML and PDF pliegos for rapid proposal submission.
- 🌐 **Multilingual Normalization:** Automatically resolves multilingual procurement titles into Spanish, English, French, or German.

***

### 💼 Ideal Use Cases

1. **B2B Agencies & IT Consultancies:** Get daily Slack/email alerts of new government software, cloud, and cybersecurity tenders in Spain and Europe.
2. **Construction & Engineering Contractors:** Monitor municipal infrastructure tenders by minimum budget and province.
3. **GovTech SaaS & Data Providers:** Build automated feeds, CRM integrations, or tender analytics dashboards for enterprise clients.
4. **Competitor & Market Intelligence:** Track which government bodies are buying what and which vendors are winning awards.

***

### ⚙️ Input Parameters

| Parameter | Type | Required | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| `country` | String | Yes | `"ESP"` | 3-letter ISO country code (`ESP` for Spain, `DEU` for Germany, `FRA` for France, `ITA` for Italy, or `ALL`). |
| `keyword` | String | No | `""` | Search keywords in tender title (e.g. `"software"`, `"ciberseguridad"`, `"limpieza"`). |
| `cpvCode` | String | No | `""` | CPV classification code (e.g. `72000000` for Computer and Related Services). |
| `minAmountEur` | Integer | No | `0` | Minimum contract value in EUR. Excludes smaller tenders below this threshold. |
| `maxItems` | Integer | Yes | `50` | Maximum number of tenders to extract per run (1 to 5,000). |
| `preferredLanguage` | String | No | `"spa"` | Preferred language for tender titles (`"spa"`, `"eng"`, `"fra"`, `"deu"`). |
| `onlyNew` | Boolean | No | `false` | When true, skips previously seen notices from past runs (ideal for scheduled alerts). |

***

### 📋 Ready-to-Copy Input Profiles

#### Preset 1: Spanish IT, Software & Cybersecurity Tenders (> €50,000)

```json
{
  "country": "ESP",
  "keyword": "software",
  "cpvCode": "72000000",
  "minAmountEur": 50000,
  "maxItems": 100,
  "preferredLanguage": "spa",
  "onlyNew": true
}
```

#### Preset 2: Pan-European Construction & Infrastructure (> €250,000)

```json
{
  "country": "ALL",
  "cpvCode": "45000000",
  "minAmountEur": 250000,
  "maxItems": 200,
  "preferredLanguage": "eng",
  "onlyNew": false
}
```

#### Preset 3: Medical Supplies & Healthcare Equipment in France & Germany

```json
{
  "country": "FRA",
  "cpvCode": "33000000",
  "minAmountEur": 100000,
  "maxItems": 100,
  "preferredLanguage": "fra",
  "onlyNew": true
}
```

***

### 📊 Sample Output Record

Each item pushed to the dataset is normalized into clean, typed JSON:

```json
{
  "noticeId": "108-2026",
  "title": "España – Servicios TI: consultoría, desarrollo de software, Internet y apoyo – Proyectos de mejora tecnológica, y la gestión integral informática de la Fundación AIC.",
  "buyer": "Fundación AIC Automotive Intelligence Center - Fundación AIC",
  "estimatedValueEur": 748000,
  "currency": "EUR",
  "publicationDate": "2026-01-02",
  "submissionDeadline": "2026-01-30T12:00:00+01:00",
  "cpvCode": "72000000",
  "country": "ESP",
  "directNoticeUrl": "https://ted.europa.eu/es/notice/108-2026/html",
  "officialPdfUrl": "https://ted.europa.eu/es/notice/108-2026/pdf",
  "source": "EU Tenders Electronic Daily (TED) v3 Official Open Data",
  "scrapedAt": "2026-09-30T16:14:26.080Z"
}
```

***

### 🤖 AI Agents & MCP Server Integration

This Actor is 100% compatible with the **Model Context Protocol (MCP)**. You can connect it directly to **Cursor, Claude Desktop, or Windsurf** using Apify's MCP server:

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/mcp-server@latest"],
      "env": {
        "APIFY_TOKEN": "YOUR_APIFY_TOKEN"
      }
    }
  }
}
```

Once connected, your AI assistant can run real-time queries like:

> *"Find all public software tenders published in Spain this month with budget over 100,000 € and summarize the deadlines."*

***

### 💰 Pricing & Economics

- **Model:** Pay-Per-Event (PPE)
- **Cost:** **$4.00 per 1,000 tenders extracted** ($0.004 per notice).
- **Free Allowance:** Apify provides **$5.00 in free usage credits every month** on all accounts, allowing users to extract over 1,200 tenders at zero cost before paying.
- **Net Margin:** Because this Actor uses direct high-speed HTTP open data with zero proxies, platform compute cost is ~$0.15-$0.20 per 1,000 items, leaving **~75%+ net developer margin**.

***

### 💻 API & Integration Code

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run_input = {
    "country": "ESP",
    "keyword": "software",
    "minAmountEur": 50000,
    "maxItems": 50,
    "onlyNew": True,
}

run = client.actor("your-username/eu-public-tenders-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"[{item['estimatedValueEur']} €] {item['title']} | Buyer: {item['buyer']}")
```

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const input = {
    country: 'ESP',
    keyword: 'software',
    minAmountEur: 50000,
    maxItems: 50,
    onlyNew: true,
};

const run = await client.actor('your-username/eu-public-tenders-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Extracted ${items.length} new public tenders.`);
```

***

### 🛡️ Legal Compliance & Open Data

All data is accessed in accordance with **Directive (EU) 2019/1024 on open data and the re-use of public sector information**. All notices are public domain government records intended for transparent commercial and civil re-use.

# Actor input Schema

## `country` (type: `string`):

ISO 3-letter country code (e.g., 'ESP' for Spain, 'FRA' for France, 'DEU' for Germany, 'ITA' for Italy, or 'ALL' for entire EU).

## `keyword` (type: `string`):

Keywords to find in the tender title (e.g. 'software', 'seguridad', 'limpieza', 'ciberseguridad'). Leave blank to fetch all.

## `cpvCode` (type: `string`):

Official EU Common Procurement Vocabulary code (e.g. 72000000 for IT services, 45000000 for Construction). Leave blank for all industries.

## `minAmountEur` (type: `integer`):

Filter tenders with total estimated contract value equal or higher than this amount in EUR.

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

Maximum number of public tender notices to extract.

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

Language code for the tender titles and descriptions.

## `onlyNew` (type: `boolean`):

When enabled, remembers previously extracted notices and only extracts newly published tenders. Perfect for scheduled daily/hourly runs.

## Actor input object example

```json
{
  "country": "ESP",
  "minAmountEur": 0,
  "maxItems": 50,
  "preferredLanguage": "spa",
  "onlyNew": false
}
```

# Actor output Schema

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

URL to the dataset containing normalized public procurement 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 = {
    "country": "ESP"
};

// Run the Actor and wait for it to finish
const run = await client.actor("metropolitan_saint/eu-public-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 = { "country": "ESP" }

# Run the Actor and wait for it to finish
run = client.actor("metropolitan_saint/eu-public-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 '{
  "country": "ESP"
}' |
apify call metropolitan_saint/eu-public-tenders-scraper --silent --output-dataset

```

## MCP server setup

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