# TED Europe Tenders – EU Public Procurement Scraper (`madeform/ted-europe-tenders`) Actor

Scrape new EU public procurement tenders from TED (Tenders Electronic Daily) for all 30 EU/EEA countries. Filter by country, CPV code, keyword or contract type. Get buyer, value, deadline, CPV labels and document links as JSON, CSV or Excel. Only-new mode for daily alerts. $3 per 1,000 tenders.

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

## Pricing

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

## TED Europe Tenders – EU public procurement scraper for all 30 EU and EEA countries

**TED Europe Tenders** collects **public procurement contract notices (tenders)** for all 27 EU countries plus Iceland, Liechtenstein and Norway from the official TED Search API (Tenders Electronic Daily). Every tender becomes one clean, structured row: buyer, **CPV code with a plain-English label**, contract type, place of performance, estimated value, **tender deadline with days left**, and direct links to the procurement documents, the submission page and the notice PDF/XML. It is made for bid teams, suppliers and analysts who want a daily or weekly list of new tenders, filtered by country, CPV code, keyword or contract type. With **Only new tenders** switched on, scheduled runs return only what you have not received before. The easiest way to try it: open the Actor and click **Start**. The default input fetches tenders from Germany and France published in the last 7 days (max 100), and **users on Apify's free plan get up to 50 tenders per run**.

**Why bid teams use it**

- **All 30 EU/EEA countries in one feed**, straight from the official TED Search API. No TED account, no API key and no proxies needed.
- **Ready to act on**: plain-English CPV labels, days left to the deadline, estimated value, and direct links to the procurement documents and the submission page.
- **Daily tender alerts without duplicates**: with `onlyNew`, each tender is returned and billed once per filter.
- **Simple pricing**: $3.00 per 1,000 tenders, no start fee, and nothing to pay when a run finds no tenders.
- **Personal data minimised**: contact names, e-mail addresses and phone numbers are removed before the data reaches you.

Only need the Nordic countries? [TED Nordic Tenders](https://apify.com/madeform/ted-nordic-tenders) has the same fields with Sweden as the default.

### Use cases

- **Bid discovery**: every morning, get new calls for tender in your CPV codes and countries, with deadlines and document links.
- **B2G sales leads**: see which public buyers are purchasing what, and at what estimated value, and feed it into your CRM or sales pipeline.
- **Tender alerts in Slack, e-mail or Teams**: combine a daily schedule with Make, Zapier or n8n.
- **Market analysis**: compare tender volumes by country, CPV sector, contract type or procedure over time.
- **AI agents and LLM pipelines**: let an assistant find, filter and summarise relevant tenders (see "Use it with AI agents" below).
- **Pay-as-you-go tender monitoring**: for small firms that follow a few sectors and don't want a tender-portal subscription.

### Example: new construction tenders in Google Sheets every morning

A construction company in Germany that also works in Austria wants to know every morning which authorities have published new building contracts. They set `countries` to `["DE", "AT"]`, `cpvCodes` to `["45000000"]` (construction work) and switch on `onlyNew`. The Actor runs on a daily schedule and is connected to Google Sheets. Each morning the sheet gets new rows only, with the buyer, title, estimated value, days left until the deadline, and links to the documents and the submission page. Tenders that were already delivered yesterday are not returned and not billed again.

### How to use TED Europe Tenders

1. Open the Actor in Apify Console and choose the **buyer countries**. Leave the field empty for all 30 EU/EEA countries.
2. Pick the **publication period** (last day, 7 days, 30 days or custom dates). Optional: add **CPV codes**, a **keyword**, a **contract type** or switch on **Only open tenders**.
3. For scheduled runs, switch on **Only new tenders since the last run**.
4. Set `maxResults` and click **Start**.
5. Open the **Output** tab to view the tenders as a table, or download them as JSON, CSV or Excel. You can also read them through the Apify API.

### Input

| Field | Description |
|---|---|
| `countries` | Buyer countries (ISO 3166-1 alpha-2, EU/EEA only), for example `["DE", "FR"]`. Empty means all 30. Greece is `GR`. |
| `datePreset` | `last1d` (yesterday and today), `last7d` (default), `last30d` or `custom`. |
| `publishedFrom` / `publishedTo` | Publication dates, `YYYY-MM-DD`. Needed for `custom`; when filled in they override the period. |
| `cpvCodes` | Optional 8-digit CPV codes, for example `45000000`. Matched by hierarchy prefix (`45000000` matches all `45…` codes, `45210000` matches `4521…`). |
| `keywords` | Optional full-text search in the notice text, in any language. |
| `contractNature` | Optional: `works`, `supplies`, `services`. Empty means all. |
| `onlyOpen` | Skip tenders whose deadline has already passed. Default `false`. Tenders with no stated deadline are kept. |
| `onlyNew` | Return only tenders not delivered by an earlier run with the same filters. Default `false`. |
| `maxResults` | 1–10,000, default 100. Free plan: at most 50 per run. |

If an input value is wrong (for example a CPV code with fewer than 8 digits or an unknown country), the run stops at once with a message that shows a valid example.

### What you get

Only **contract notices** (calls for tender; form types cn-standard, cn-social, cn-desg). The Actor does not return award notices, winners, tenderers, prior-information notices or contact details. One row per notice.

| Field | Meaning |
|---|---|
| `publicationNumber`, `publicationDate`, `noticeType` | TED notice number, publication date, notice type. |
| `title`, `titleEnglish`, `description` | Title in the notice language, English notice title, short description (max 500 characters, sanitized). |
| `buyerName`, `buyerCountry`, `buyerCity`, `buyerWebsite` | The contracting authority, its country (ISO 2-letter), city and website. |
| `contractNature` | `works`, `supplies` or `services`. |
| `cpvCodes`, `cpvDescriptions` | CPV codes and their official English labels, in the same order. `null` where a code is not in the vocabulary. |
| `mainCpvCode`, `mainCpvDescription` | The first CPV code and its label. |
| `placeOfPerformanceCountries`, `placeOfPerformanceCity`, `nutsCodes` | Where the contract is performed: countries (ISO 2-letter), city or area as written in the notice, NUTS region codes (for example `DE212`). |
| `estimatedValue`, `currency` | Estimated total value, when the notice states one. |
| `tenderDeadline`, `participationRequestDeadline` | Deadline for tenders, and for requests to participate (restricted and negotiated procedures). |
| `daysUntilDeadline` | Whole days from retrieval to the earlier of the two deadlines. Negative if it has passed, `null` if no deadline is stated. |
| `procedureType` | For example `open`. |
| `documentsUrl`, `submissionUrl` | Where the procurement documents are published and where tenders are submitted (usually the buyer's e-procurement platform, which can require a free registration). |
| `pdfUrl`, `xmlUrl`, `tedUrl` | The notice as PDF (English if available) and XML, and its page on TED. |
| `officialLanguages` | Official language(s) of the notice as TED returns them: three-letter codes such as `DEU`, `FRA`, `ITA`. |
| `source`, `license`, `retrievedAt` | Attribution, licence statement and the time the notice was fetched. |

URL fields that contain an e-mail address (`@` or `mailto:`) are set to `null`; the rest of the row is kept.

### Example output

These rows come from a real run on 28 October 2026 with five countries (DE, AT, PL, IT, ES), CPV codes 45000000 (construction work) and 72000000 (IT services) and the last 7 days (run `eOz0bQUcpd6ePcSnM`, 50 rows on the free plan). The table shows the most important columns of five of them; values are unchanged.

| publicationNumber | buyerCountry | buyerName | title | mainCpvDescription | estimatedValue | currency | tenderDeadline | daysUntilDeadline |
|---|---|---|---|---|---|---|---|---|
| 745273-2026 | DE | AWO Niedersachsen gGmbH | Neubau einer kinder- und jugendpsychiatrischen Einrichtung, hier Elektroanlagen | Construction work | 1688000 | EUR | 2026-11-30T10:00:00+01:00 | 32 |
| 745433-2026 | IT | COMUNE DI SANSEPOLCRO - Ambiente | Palazzetto dello Sport lavori di adeguamento sismico US3. | Construction work for sports facilities | 1386096.4 | EUR | 2026-11-06T08:00:00+02:00 | 8 |
| 745549-2026 | PL | Centrum e-Zdrowia | Świadczenie Usługi Serwisu Urządzeń wraz z Oprogramowaniem będących w posiada… | IT services: consulting, software development, Internet and support | 2073858 | PLN | 2026-11-04T12:00:00+01:00 | 7 |
| 745415-2026 | ES | Alcaldía del Ajuntament de Llucmajor | Servicio de gestión integral de los servicios del cementerio municipal (opera… | Cemetery services and cremation services | 641627.84 | EUR | 2026-11-25T23:59:00+01:00 | 28 |
| 745377-2026 | AT | Kärntner Flughafen Betriebs GesmbH | FHK - Hotel | Hotel construction work |  |  |  | 62 |

A whole row as JSON (same run). `daysUntilDeadline` is counted when the row is fetched.

```json
{
  "publicationNumber": "745433-2026",
  "publicationDate": "2026-10-28",
  "noticeType": "cn-standard",
  "title": "Palazzetto dello Sport lavori di adeguamento sismico US3.",
  "titleEnglish": "Italy – Construction work for sports facilities – Palazzetto dello Sport lavori di adeguamento sismico US3.",
  "description": "Lavori di adeguamento sismico US3 nell'ambito dell'intervento generale di adeguamento sismico US1 e US3 del Palazzetto dello Sport.",
  "buyerName": "COMUNE DI SANSEPOLCRO - Ambiente",
  "buyerCountry": "IT",
  "buyerCity": "Sansepolcro",
  "buyerWebsite": null,
  "contractNature": "works",
  "cpvCodes": [
    "45212200"
  ],
  "cpvDescriptions": [
    "Construction work for sports facilities"
  ],
  "mainCpvCode": "45212200",
  "mainCpvDescription": "Construction work for sports facilities",
  "placeOfPerformanceCountries": [
    "IT"
  ],
  "placeOfPerformanceCity": null,
  "nutsCodes": [],
  "estimatedValue": 1386096.4,
  "currency": "EUR",
  "tenderDeadline": "2026-11-06T08:00:00+02:00",
  "participationRequestDeadline": "2026-11-06T08:00:00+02:00",
  "daysUntilDeadline": 8,
  "procedureType": "open",
  "documentsUrl": "https://start.toscana.it/tendering/tenders/037969-2026/view/detail/1",
  "submissionUrl": "https://www.start.toscana.it",
  "pdfUrl": "https://ted.europa.eu/en/notice/745433-2026/pdf",
  "xmlUrl": "https://ted.europa.eu/en/notice/745433-2026/xml",
  "officialLanguages": [
    "ITA"
  ],
  "tedUrl": "https://ted.europa.eu/en/notice/-/detail/745433-2026",
  "source": "TED – Tenders Electronic Daily, European Union, https://ted.europa.eu",
  "license": "Reuse authorised under Commission Decision 2011/833/EU; data modified (contact details removed, text shortened)",
  "retrievedAt": "2026-10-28T10:50:12.448Z"
}
```

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

The Actor uses pay per event pricing: **$3.00 per 1,000 tender notices** ($0.003 per saved row), with no start fee and no charge for runs that find nothing. One tender row saved equals one billed event.

Example: a run that saves 1,000 tenders costs $3.00. A run that saves 100 tenders (the default maximum) costs $0.30, and a daily `onlyNew` run that finds 20 new tenders costs $0.06.

| Typical setup | Tenders saved | Cost |
|---|---|---|
| One test run with the default input | up to 100 | up to $0.30 |
| Daily alert for construction (CPV 45000000) in Germany and Austria, as in the example above (3,070 tenders in the 30 days to 27 Oct 2026) | about 3,100 a month | about $9.20 a month |
| Weekly pull of all EU/EEA construction tenders, CPV 45000000 (1,766 in the week 21–27 Oct 2026) | about 7,600 a month | about $23 a month |
| One-off export of 10,000 tenders | 10,000 | $30.00 |

The figures are examples. You pay only for the tenders that are actually saved, and you can cap the cost of any run with **Maximum cost per run** in the run options.

**Free plan:** users on Apify's free plan get at most **50 tenders per run**. For plans and platform credits, see [Apify pricing](https://apify.com/pricing).

**No double billing with `onlyNew`:** with the same filters, a tender is returned and billed once. Later runs skip it.

### Schedule it and connect it

- **Schedule:** run the Actor every day or week with [Apify schedules](https://docs.apify.com/platform/schedules). For a daily list, combine the schedule with `onlyNew`.
- **API:** start runs and read the dataset through the Apify API.
- **Integrations:** send new rows to other tools through [Apify integrations](https://docs.apify.com/platform/integrations), for example [Make](https://docs.apify.com/platform/integrations/make), [Zapier](https://docs.apify.com/platform/integrations/zapier), [n8n](https://docs.apify.com/platform/integrations/n8n) or [Slack](https://docs.apify.com/platform/integrations/slack).
- **Google Sheets:** use the Actor [Google Sheets Import & Export](https://apify.com/lukaskrivka/google-sheets) to write the dataset to a spreadsheet.
- **Export:** download the dataset as JSON, CSV or Excel.

### Use it from your code: cURL, Python and JavaScript

You can start TED Europe Tenders and read the results through the [Apify API](https://docs.apify.com/api/v2). Get your API token in Apify Console under [Settings → API & Integrations](https://console.apify.com/settings/integrations) and set it as the environment variable `APIFY_TOKEN`. The snippets below were run against this Actor on 28 October 2026.

**cURL**: start a run, wait for it and get the rows in one request. The synchronous endpoint waits up to 5 minutes, so use it for small and medium runs.

```bash
curl -X POST "https://api.apify.com/v2/acts/madeform~ted-europe-tenders/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"countries":["DE","AT"],"cpvCodes":["45000000"],"datePreset":"last7d","maxResults":50}'
```

**Python** (`pip install apify-client`, tested with version 3.4):

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("madeform/ted-europe-tenders").call(run_input={
    "countries": ["SE", "DK"],
    "cpvCodes": ["72000000"],
    "datePreset": "last30d",
    "maxResults": 50,
})
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item["publicationNumber"], item["buyerName"], item["tenderDeadline"])
```

With apify-client 1.x or 2.x, `call()` returns a dict: use `run["defaultDatasetId"]` instead of `run.default_dataset_id`.

**JavaScript / TypeScript** (`npm install apify-client`, tested with version 2.25):

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('madeform/ted-europe-tenders').call({
    countries: ['SE', 'DK'],
    cpvCodes: ['72000000'],
    datePreset: 'last30d',
    maxResults: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) console.log(item.publicationNumber, item.buyerName, item.tenderDeadline);
```

The **API** tab on this Actor's page has more examples and the full OpenAPI definition.

### Use it with AI agents (MCP)

TED Europe Tenders also works as a tool for AI assistants and agents through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp). Add this server URL to Claude, Cursor, VS Code or any other MCP client, and sign in with your Apify account when asked:

```text
https://mcp.apify.com?tools=madeform/ted-europe-tenders
```

Then ask in plain language, for example: *"Find open IT services tenders from Sweden and Denmark published in the last 7 days and list them by deadline, with buyer, estimated value and document link."* The agent fills in the input (`countries`, `cpvCodes`, `datePreset`, `onlyOpen`, `maxResults`), runs the Actor and reads the rows. Agent runs are billed exactly like normal runs, one event per saved row.

### FAQ

#### Is it legal to use TED data?

TED data is published by the Publications Office of the European Union and may be reused under [Commission Decision 2011/833/EU](https://eur-lex.europa.eu/eli/dec/2011/833/oj/eng). The Actor modifies the data (see "Data source and licence" below). You are responsible for how you use the output.

#### How up to date is the data?

Every run fetches the notices live from the TED Search API. The Actor does not keep its own archive, so the result depends on what TED has published for your period at the time of the run. Each row has a `retrievedAt` timestamp.

#### Which tenders are covered?

Contract notices published in TED where the buyer is in one of the 30 EU/EEA countries. National procurements below the EU thresholds are usually not included, because they generally do not have to be published in TED. Award notices and winners are not collected, and there are no contact details.

#### How does "only new" work?

With `onlyNew` the Actor remembers how far the last run got and returns only tenders published after that point. It stores the last publication date and the publication numbers it has already handled on that date, nothing else, in a key-value store named `ted-europe-tenders-state` in your own Apify account. The memory is kept per filter: a different combination of countries, CPV codes, keywords, contract types or `onlyOpen` has its own history, so one schedule does not affect another. The first run with a given filter uses your publication period. After that the period is ignored and the run continues after the last tender delivered, oldest publication day first. If a run stops early (`maxResults`, the free plan limit or your maximum charge), the next run continues where it ended and skips nothing. To start over, delete the key `state-…` in that store.

#### Does the data contain personal data?

The Actor requests only a fixed list of fields and removes e-mail addresses, telephone numbers, personal identity numbers and contact names from free text, in the main EU languages. Notices may still contain personal data, for example names in free text. See "Minimised personal data" below.

#### How do I filter by CPV code?

Add one or more 8-digit codes to `cpvCodes`. Matching is by hierarchy prefix, so `45000000` matches all construction codes starting with `45`. Each row also carries the English label of every CPV code.

#### Why are some fields `null`?

The Actor shows only what the notice states. Many notices have no estimated value, some have no tender deadline in the form TED returns, and not every buyer lists a website or a submission link. A `null` means the notice did not provide the value.

#### What do I get on the free plan?

Up to 50 tenders per run. For paid usage see the pricing section above.

#### Can I see who won a tender?

No. The Actor returns contract notices only, not award notices or winners.

#### How is this different from searching on TED?

TED's website is made for reading notices one at a time. This Actor turns them into uniform rows with English CPV labels, deadlines in days and direct document links, remembers what you have already received, and sends the result to a spreadsheet, your CRM, an API client or an AI agent on a schedule.

#### Can I get the tenders in Slack or by e-mail?

Yes. Schedule the Actor with `onlyNew` and connect the run to Slack, e-mail, Make, Zapier or n8n through [Apify integrations](https://docs.apify.com/platform/integrations). Each new tender then reaches you once.

#### Can I use it from my own code or an AI agent?

Yes. See "Use it from your code" and "Use it with AI agents (MCP)" above.

### Minimised personal data

The Actor is built to keep personal data to a minimum:

- It asks the TED API only for a fixed whitelist of fields. Contact names, e-mail addresses, telephone numbers, winners and tenderers are never requested, and only contract notices (no award notices) are collected.
- Free text (title, description, buyer name, city, place of performance) is scrubbed of e-mail addresses (including obfuscated forms such as `name(at)example.de`), telephone numbers and national identity numbers. Names that follow words such as "contact person", "Ansprechpartner", "personne de contact", "persona de contacto", "responsabile del procedimento" or "contactpersoon" are removed as well. Removed parts are replaced by `[removed]`. Organisation names are kept.
- Links that contain an e-mail address are dropped.
- The only state kept between runs (`onlyNew`) is a date and publication numbers. It holds no notice data.

Notices may still contain personal data (for example names in free text). You are the controller for your use of the output. Check your legal basis (typically legitimate interest), your information duties under GDPR Art. 14 and your retention period. Do not use the data for direct marketing to individuals.

Data storage: Apify stores datasets in AWS us-east-1 (USA) under Apify's [Data Processing Addendum](https://docs.apify.com/legal/data-processing-addendum) with Standard Contractual Clauses (SCC); see Apify's [shared responsibility model](https://docs.apify.com/security/shared-responsibility). If you need to keep the data in the EU, export it and delete the dataset after the run.

### Data source and licence

Source: TED – Tenders Electronic Daily, Publications Office of the European Union, © European Union, reused under [Commission Decision 2011/833/EU](https://eur-lex.europa.eu/eli/dec/2011/833/oj/eng). Retrieved via the TED Search API on the date given in each row's `retrievedAt` field. See the [TED legal notice](https://ted.europa.eu/en/legal-notice).

**The data is modified.** Contact details and identity numbers are removed and replaced by `[removed]`, contact names after keywords are removed, and descriptions are shortened to 500 characters. Fields are reformatted (dates, values, country codes), and links containing e-mail addresses are dropped. The original notice is the one at `tedUrl` on TED.

CPV labels: the Common Procurement Vocabulary (CPV) is established by Commission Regulation (EC) No 213/2008. The English labels come from EU Vocabularies, Publications Office of the European Union.

This Actor is an independent tool. It is not affiliated with, endorsed by or operated by the European Union or the Publications Office of the EU.

### More from Madeform

- [TED Nordic Tenders](https://apify.com/madeform/ted-nordic-tenders) – tenders from Sweden, Norway, Denmark, Finland and Iceland only, with Sweden as the default, $3.00 per 1,000 tenders.
- [Trafikverket Disruptions](https://apify.com/madeform/trafikverket-disruptions) – Swedish road incidents, roadworks, rail disruptions and train delays from Trafikverket open data, $1.00 per 1,000 rows.

# Actor input Schema

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

Countries of the buyer (contracting authority) to collect tenders for. Select one or more EU/EEA countries. Leave empty for all 30 EU/EEA countries.

## `datePreset` (type: `string`):

Which publication dates to include. 'Last day' means yesterday and today. Choose 'Custom dates' to use the two date fields below. With 'Only new tenders' switched on, this period is used for the first run only; later runs continue after the last tender delivered.

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

Used with 'Custom dates' (or whenever filled in, it overrides the period). First publication date to include, format YYYY-MM-DD, for example 2026-10-01.

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

Last publication date to include, format YYYY-MM-DD. Leave empty for today.

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

Optional. 8-digit CPV codes (the EU classification of what is procured), for example 45000000 for construction work or 72000000 for IT services. Matching is by prefix of the code hierarchy: 45000000 matches all codes starting with 45, 45210000 matches 4521…. Leave empty for all categories.

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

Optional. Free-text search in the notice text, in any language, for example: school building. Leave empty for no keyword filter.

## `contractNature` (type: `array`):

Optional. Only tenders of these types. Leave empty for all types.

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

Skip tenders whose tender or application deadline has already passed. Tenders without a stated deadline are kept.

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

Return only tenders you have not received in an earlier run with the same filters (countries, CPV codes, keywords, contract type, 'only open'). Use it for scheduled runs so you never pay for the same tender twice. The Actor remembers only the last publication date and the publication numbers of that date, in a key-value store named 'ted-europe-tenders-state' in your account.

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

Maximum number of tenders to save (1–10,000). Each saved tender is one billed event. Users on Apify's free plan get at most 50 per run.

## Actor input object example

```json
{
  "countries": [
    "DE",
    "FR"
  ],
  "datePreset": "last7d",
  "cpvCodes": [
    "45000000",
    "72000000"
  ],
  "keywords": "software",
  "onlyOpen": false,
  "onlyNew": false,
  "maxResults": 100
}
```

# Actor output Schema

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

EU/EEA contract notices from TED, one row per notice, in the run's 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 = {
    "countries": [
        "DE",
        "FR"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("madeform/ted-europe-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 = { "countries": [
        "DE",
        "FR",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("madeform/ted-europe-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 '{
  "countries": [
    "DE",
    "FR"
  ]
}' |
apify call madeform/ted-europe-tenders --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,madeform/ted-europe-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/L4ACZL3oQsFYIaKCZ/builds/5HULv392QFMzeoBGu/openapi.json
