# EU Tenders Scraper: TED Public Procurement | $1/1K (`one_dollar_store/eu-tenders-ted-scraper`) Actor

$1 per 1,000 results, platform usage included. EU public procurement notices from TED (Tenders Electronic Daily): title, buyer, country, publication date, deadline, CPV codes, value and notice links. Filter by keyword, country, CPV code and date. No API key.

- **URL**: https://apify.com/one_dollar_store/eu-tenders-ted-scraper.md
- **Developed by:** [One Dollar Store](https://apify.com/one_dollar_store) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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

## EU Tenders Scraper: public procurement notices from TED

**$1 per 1,000 notices. Platform usage included. No rental, no minimum.**

[Open it in Apify Console](https://console.apify.com/actors/Ihaus7CfmhbDWi9TO/input)

### What it costs

| Notices | This actor |
|---|---|
| 1,000 | $1.00 |
| 10,000 | $10.00 |
| 100,000 | $100.00 |

Plus $0.001 per run. One flat price, platform usage included, so there is no separate compute or proxy bill. A daily run of 200 new notices costs about $0.20, or about $6 a month.

### Why use it

- **The official source.** Rows come from TED (Tenders Electronic Daily), the EU's journal for public procurement, through its own open search API. No key and no web page scraping.
- **Open calls and results.** Contract notices (open calls for tenders), results (contract awards, with the winner names) and planning notices (prior information).
- **Filters done by TED.** Keywords, buyer country, CPV code (a short code such as 72 matches everything under it), date range, value range and "still open" run on TED's side, so you pay only for the notices you keep.
- **Big pulls are fast.** A 1,000 notice run took about 85 seconds in our tests.

### Quick start

1. Open the actor, type a keyword, press **Start**.
2. Or paste this input:

```json
{ "keywords": ["software"], "countries": ["DE", "FR"], "cpvCodes": ["72"], "noticeKind": "competition", "onlyOpen": true, "daysBack": 14, "maxItems": 100 }
```

3. Download the results as JSON, CSV or Excel, or read them through the API.

### Use it from code

```bash
curl -X POST "https://api.apify.com/v2/acts/one_dollar_store~eu-tenders-ted-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["cloud"], "daysBack": 7, "maxItems": 50}'
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("one_dollar_store/eu-tenders-ted-scraper").call(
    run_input={"countries": ["Germany"], "cpvCodes": ["72"], "daysBack": 7, "maxItems": 100}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["publishedOn"], item["buyerCountry"], item["buyerName"], item["title"], item.get("value"))
```

### Use it from an AI assistant

Claude, ChatGPT, Cursor and other assistants can call this actor through Apify's MCP server. Add it with this server address:

```
https://mcp.apify.com?tools=one_dollar_store/eu-tenders-ted-scraper
```

Then ask, for example: "Find open EU tenders for IT services published in the last 10 days with a value above 200,000 euros."

### Switching from another TED actor

Most take a search text, a country and a result limit. Here they are `keywords` (a list), `countries` (two letter codes, three letter codes or names) and `maxItems`, with `daysBack` or `publishedFrom` and `publishedTo` for dates. The core fields are `noticeId`, `title`, `buyerName`, `buyerCountry`, `cpvCodes`, `value`, `deadline` and `noticeUrl`.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `keywords` | list of text | none | Full text search in the notice (title, description, buyer). A notice is kept when it matches any line. |
| `countries` | list | none | Buyer countries as two letter codes (`DE`), three letter codes (`DEU`) or English names (`Germany`). |
| `cpvCodes` | list | none | CPV codes. A short code such as `72` or `7222` also matches every code that starts with it. |
| `noticeKind` | text | `any` | `competition` (open calls), `result` (contract awards) or `planning` (prior information). |
| `daysBack` | number | 7 | Notices published in the last N days (up to 3,650). |
| `publishedFrom`, `publishedTo` | text | none | Dates such as `2026-09-01`. They replace `daysBack`. |
| `onlyOpen` | true or false | false | Only notices whose submission deadline has not passed. |
| `minValue`, `maxValue` | number | none | Keep notices whose estimated or total value is in this range, in the notice's own currency. |
| `maxItems` | number | 100 | Total notices for the run. Minimum 10. |

Example:

```json
{
  "keywords": ["software", "cloud services"],
  "countries": ["DE", "FR"],
  "cpvCodes": ["72"],
  "noticeKind": "competition",
  "minValue": 100000,
  "onlyOpen": true,
  "daysBack": 14,
  "maxItems": 100
}
```

### Output fields

| Field | Meaning |
|---|---|
| `noticeId` | TED publication number, for example `700338-2026`. |
| `title`, `sector` | The buyer's own title and the main CPV label TED shows in front of it. |
| `noticeType`, `contractNature`, `procedureType` | TED notice type (`cn-standard`, `can-standard`, `pin-only`...), `works`, `services` or `supplies`, and the procedure (`open`, `restricted`...). |
| `buyerName`, `buyerCountry`, `buyerCountryName` | Contracting authority (English text when TED has it, else the original language) and its country. |
| `cpvCodes` | CPV codes of the notice, without repeats. |
| `publishedOn`, `deadline` | Publication date and the earliest submission deadline among the lots. |
| `value`, `valueCurrency`, `valueKind` | Estimated value for open calls and the awarded total for results, in the notice's currency. `valueKind` says which. |
| `winners` | For result notices: the winning company names (up to 100). |
| `noticeUrl`, `pdfUrl`, `xmlUrl` | Links to the notice on TED, its PDF and its XML. |
| `scrapedAt` | Collection time. |

### Sample results

Real rows from test runs on 9 October 2026 (titles and winner lists shortened).

```json
[
 {
  "noticeId": "700338-2026",
  "title": "Mobilier de bibliothèque et rayonnage - 2 lots",
  "sector": "Furniture",
  "noticeType": "cn-standard",
  "contractNature": "supplies",
  "procedureType": "open",
  "buyerName": "Conseil Départemental de l'Essonne",
  "buyerCountry": "FRA",
  "buyerCountryName": "France",
  "cpvCodes": [
   "39100000",
   "39120000",
   "39131100"
  ],
  "publishedOn": "2026-10-09",
  "deadline": "2026-11-09",
  "value": 3000000,
  "valueCurrency": "EUR",
  "valueKind": "estimated",
  "noticeUrl": "https://ted.europa.eu/en/notice/-/detail/700338-2026"
 },
 {
  "noticeId": "700330-2026",
  "title": "Vispārīgā vienošanās kokskaidu granulu piegādei Madonas novada pašvaldībai",
  "sector": "Wood fuels",
  "noticeType": "can-standard",
  "contractNature": "supplies",
  "procedureType": "open",
  "buyerName": "Madonas novada pašvaldība",
  "buyerCountry": "LVA",
  "buyerCountryName": "Latvia",
  "cpvCodes": [
   "09111400"
  ],
  "publishedOn": "2026-10-09",
  "value": 500000,
  "valueCurrency": "EUR",
  "valueKind": "total",
  "winners": [
   "Sabiedrība ar ierobežotu atbildību \"AKVARIUS\"",
   "Sabiedrība ar ierobežotu atbildību \"Latgales Granulas\""
  ],
  "noticeUrl": "https://ted.europa.eu/en/notice/-/detail/700330-2026"
 },
 {
  "noticeId": "700335-2026",
  "title": "Umbau Alte Weberei zum KreativCampus - Los 09 Trockenbau",
  "sector": "Construction work",
  "noticeType": "cn-standard",
  "contractNature": "works",
  "procedureType": "open",
  "buyerName": "Stadt Finsterwalde",
  "buyerCountry": "DEU",
  "buyerCountryName": "Germany",
  "cpvCodes": [
   "45000000"
  ],
  "publishedOn": "2026-10-09",
  "deadline": "2026-11-10",
  "noticeUrl": "https://ted.europa.eu/en/notice/-/detail/700335-2026"
 }
]
```

### Limits

- **One row per notice.** A notice with many lots is one row. Lot titles and lot values are not listed separately.
- **Value is often missing.** Many open calls give no value at notice level, and TED shows values per lot instead. In a 50 notice test run about half the rows had a value. `minValue` and `maxValue` drop notices with no stated value.
- **Deadline** is the earliest submission deadline among the lots. Result notices have none. Dates have no time of day.
- **Language.** Titles and buyer names come in the language the buyer used. The English text is used when TED has it.
- **Keywords** are matched by TED's full text search. Quotes and backslashes in keywords are removed before the search.
- **Coverage.** TED holds notices above the EU thresholds and some below them. Contracts a country publishes only on its own portal are not here.
- **Pace.** The actor makes about two requests a second and reads up to 250 notices per request. A 1,000 notice run took about 85 seconds in our tests.

### FAQ

**How much does it cost to scrape 10,000 EU tenders?**
$10, plus $0.001 for each run.

**Do I pay for compute or proxy on top?**
No. Platform usage is included in the $1 per 1,000 price. The actor needs no proxy.

**Where does the data come from?**
From the search API of TED (Tenders Electronic Daily), the EU's official procurement journal. The API is open to everyone and needs no key. The actor uses no login.

**Can I see who won a contract?**
Yes. Set `noticeKind` to `result`. Result notices list the winners in `winners` and the awarded total in `value`.

**How do I get only tenders I can still bid on?**
Set `noticeKind` to `competition` and turn on `onlyOpen`.

**Can I watch for new tenders every day?**
Yes. Schedule a daily run with `daysBack` set to 1 and use `noticeId` to drop notices you already have.

**Is it legal?**
The actor reads public data only, with no login. TED notices are published for reuse by the EU. How you use them is up to you: follow the reuse conditions on TED, data protection law for any personal data, and the law where you live.

**Is this an official EU product?**
No. It is an independent tool and is not affiliated with or endorsed by the European Union or the Publications Office of the EU.

**Do I need an Apify account?**
Yes. Actors run from an Apify account, and a free account is enough to start: it includes $5 of platform usage every month. You can [sign up here](https://www.apify.com?fpr=ymnoit). This is a referral link and it costs you nothing.

**Is there a limit on the free plan?**
Yes. A run started from a free plan account delivers the first 10 results, then ends with a message and a link to the plans. Any paid plan returns everything you ask for, up to your own limit. The price per result is the same on every plan.

### More from The One Dollar Store

Every actor here costs $1 per 1,000 results, platform usage included. See the whole store: https://apify.com/one_dollar_store

**Tenders and grants**

- [UK Contracts Finder Scraper](https://apify.com/one_dollar_store/uk-contracts-finder-tenders): UK public tenders and awards.
- [USAspending Scraper](https://apify.com/one_dollar_store/usaspending-awards-scraper): US federal contracts and awards.
- [Grants.gov Scraper](https://apify.com/one_dollar_store/grants-gov-opportunities-scraper): US federal grant opportunities.

**Google and search**

- [Google News Scraper](https://apify.com/one_dollar_store/google-news-articles-scraper): News articles by keyword, topic or country.

### Changelog

- October 2026: first release.

# Actor input Schema

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

Optional. One search per line, matched against the full text of the notice (title, description, buyer). A notice is kept when it matches any line.

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

Optional. Two letter codes (DE), three letter codes (DEU) or English names (Germany). Only notices from buyers in these countries.

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

Optional. Common Procurement Vocabulary codes. A short code such as 72 or 7222 also matches every code that starts with it.

## `noticeKind` (type: `string`):

Contract notices are open calls for tenders, results are contract award notices, planning are prior information notices.

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

Notices published in the last N days. Ignored when you set a start date below.

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

Optional start date, for example 2026-09-01. Overrides Days back.

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

Optional end date, for example 2026-09-30. Default is today.

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

Keep notices whose submission deadline has not passed yet (TED's active scope).

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

Optional. Keep notices whose estimated or total value is at least this much.

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

Optional. Keep notices whose estimated or total value is at most this much.

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

The run stops after this many notices. Minimum 10.

## Actor input object example

```json
{
  "noticeKind": "any",
  "daysBack": 3,
  "onlyOpen": false,
  "maxItems": 50
}
```

# 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 = {
    "daysBack": 3,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("one_dollar_store/eu-tenders-ted-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 = {
    "daysBack": 3,
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("one_dollar_store/eu-tenders-ted-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 '{
  "daysBack": 3,
  "maxItems": 50
}' |
apify call one_dollar_store/eu-tenders-ted-scraper --silent --output-dataset

```

## MCP server setup

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