# TED Tenders Scraper: EU Public Procurement Alerts to Excel (`alpine-data/ted-tender-monitor`) Actor

TED tenders scraper for EU public procurement: pick countries and a sector, get new tenders with deadline, buyer and value as Excel. Daily alerts.

- **URL**: https://apify.com/alpine-data/ted-tender-monitor.md
- **Developed by:** [Alpine Data Labs](https://apify.com/alpine-data) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Tenders Scraper: EU public procurement notices and tender alerts as Excel

Find **new EU tenders** (TED tenders: EU public procurement notices) from the official TED database (Tenders Electronic Daily) for Austria, Germany or the whole EU, and download them as **Excel, CSV or JSON**. No coding, no login, no API key: pick your countries, click **Start**, download. Schedule it for daily **tender alerts**.

### How to find EU tenders in 4 steps (no code)

1. **Pick your countries** (e.g. Austria, Germany) and, if you like, a **sector** from the dropdown (e.g. *72 – IT services*). The form is already filled in with a working example.
2. Click **Start**. A run takes 5–30 seconds. **Note: Start with the pre-filled example is a small paid run:** about 100–150 IT tenders from Austria + Germany × $0.003, usually $0.30–0.45 and never more than *Max notices* (200 = $0.60).
3. Open the **Output** tab and click **Export** to download **Excel** or **CSV**.
4. **Optional: get a daily alert.** Turn on *Only new notices*, save as a *Task* and add a daily *Schedule* (see below). Send results by email, Google Sheets, Slack, Make, Zapier or n8n via the *Integrations* tab. No code needed.

### What you get from each TED tender

| Deadline | Days left | Tender | Buyer | Country | Est. value | Link |
|---|---|---|---|---|---|---|
| 2026-11-16 | 24 | Österreich – Softwareprogrammierung und -beratung – Holding Graz - Backend-Vertrieb & Frontend | Holding Graz - Kommunale Dienstleistungen GmbH | AUT | 900,000 EUR | [open](https://ted.europa.eu/en/notice/-/detail/722560-2026) |
| 2026-11-30 | 38 | Österreich – IT-Dienste: Beratung, Software-Entwicklung, Internet und Hilfestellung – Abschluss einer Rah… | Wiener Tourismusverband | AUT | 500,000 EUR | [open](https://ted.europa.eu/en/notice/-/detail/717034-2026) |

*(Real rows from a test run on 23 Oct 2026 with the pre-filled example.)* Every row also has the English title, buyer city, CPV codes, place of performance, notice type, procedure, publication date and a PDF link (see the *All details* view).

### EU public procurement scraper: CPV codes and countries

Pick one or more EU countries and a sector. Each sector is a CPV category, the EU's procurement classification, and a main category includes all its sub-categories. You can also type CPV codes (e.g. 72000000) directly. The scraper returns recent public procurement notices from TED (Tenders Electronic Daily) with notice number, title, buyer, country, deadline and, if the buyer published it, the estimated value. Run it daily as a tender alert for Ausschreibungen in Austria, Germany or the whole EU.

### Daily tender alert: schedule it

> **Schedule it daily:** click **Schedule** (or *Saved tasks → Schedule*) and run it every morning at 07:00 with **Only new notices since my last run** switched on. Each run then returns only tenders you have not seen before, which gives you a tender alert without a subscription. Connect email, Slack, Google Sheets or Zapier/Make under *Integrations*.

### Öffentliche Ausschreibungen aus Österreich und Deutschland

Der Actor findet **öffentliche Ausschreibungen** aus Österreich, Deutschland und der ganzen EU (EU-weite Ausschreibungen ab den EU-Schwellenwerten) ohne Programmieren: Land wählen, Branche wählen (z. B. *72 – IT-Dienste* für **IT-Ausschreibungen** oder *45 – Bauarbeiten* für **Bauausschreibungen**), auf **Start** klicken und als **Excel** herunterladen. Mit *Only new notices since my last run* und einem täglichen Zeitplan wird daraus ein kostenloser Ausschreibungs-Alert.

### Typical uses

- **Daily tender alert** for your sector, e.g. IT services in Austria and Germany
- **Sales pipeline**: send new tenders to Google Sheets, Slack, a CRM, n8n, Make or Zapier
- **Market research**: with *Contract award notices*, see who won which contract and at what value

### Input fields in plain words

![TED tenders scraper input form: EU public procurement search by country and sector](https://api.apify.com/v2/key-value-stores/jVsR1fgZbtwc50gQM/records/ted-tender-monitor-input-form)

| Field | What it does | Example |
|---|---|---|
| **Which countries?** | Country of the public buyer. Choose *All countries* for the whole EU/EEA. You can also type names or codes: `Österreich`, `AT` and `AUT` all work. If you leave it empty, the default Austria + Germany is searched (the run status says so). | Austria, Germany |
| **Which sector?** | EU product/service category (CPV). A main category includes all sub-categories. You can also type a code (`90910000`, `72000000-8`) or a word (`Reinigung`, `IT`). | 72 – IT services |
| **Keywords** | Finds notices that mention *any* of these words, in any language. Commas or new lines separate words. | Software, Cloud |
| **Published in the last … days** | How far back to look. | 7 |
| **Max notices (cost limit)** | The run stops here, so you never pay more than you expect. | 200 (max. $0.60) |
| **Only new notices since my last run** | For daily alerts: skips notices you already received. Skipped notices are free. | on |
| **Alert name** | Only needed if you run several different alerts. | vienna-it |
| *Advanced:* Notice types | Open calls for tender (default), planned tenders, or award notices (who won). | Open calls for tender |
| *Advanced:* Only tenders that are still open | Drops notices whose deadline has passed (free). | on |
| *Advanced:* Minimum estimated value | Keeps notices with a published value at or above this amount (others are skipped and free). | 100000 |
| *Advanced:* Published from | Exact start date instead of "last … days". `2026-10-01`, `01.10.2026`, `yesterday`/`gestern` and `today`/`heute` all work. | 2026-10-01 |
| *Advanced:* Language | Language for title, buyer and link. | German, English |

### Output fields

![TED tenders scraper example output: EU public procurement notices with buyer, country and deadline](https://api.apify.com/v2/key-value-stores/jVsR1fgZbtwc50gQM/records/ted-tender-monitor-example-output)

`publicationNumber`, `title`, `titleEnglish`, `buyerName`, `buyerCity`, `buyerCountry`, `publicationDate`, `deadline`, `deadlineType` (`tender_submission` or `request_to_participate`), `daysUntilDeadline`, `noticeType` (TED code, e.g. `cn-standard`), `noticeTypeLabel` (plain words, e.g. *Call for tenders*), `procedureType`, `contractNature`, `cpvCodes`, `placeOfPerformance` (NUTS codes), `estimatedValue`, `currency`, `url`, `pdfUrl`, `source`.

### Pricing

Pay per result: **$0.003 per tender notice** returned, which is **$3.00 per 1,000 notices**. There is no start fee and no monthly fee. Notices skipped by *Only new notices* are free.

These are **launch prices** while the Actor builds its first user base. If prices change, Apify notifies existing users in advance, as its rules require. Platform usage is included in the price.

Higher Apify plans pay less: SILVER 10 % off, GOLD and above 20 % off.

### FAQ and common mistakes

**Which CPV code do I need?** CPV codes are the EU's sector codes for public procurement. Pick a main category from the *Which sector?* dropdown (e.g. *72 – IT services*, *45 – Construction work*, *79 – Business services*). It includes all sub-codes. You can also type a code such as `72000000` or a word such as `IT`.

**Do I need a TED API key or an account at TED?** No. The Actor uses the public TED API for you. You only need a free Apify account.

**How do I find IT tenders or construction tenders?** Choose *72 – IT services* or *45 – Construction work* under *Which sector?* and your countries. There are ready-made examples in the *Examples* section of this page.

**I got 0 results. What now?** Your filters are too narrow. Try more days back (e.g. 30), remove keywords, choose a main sector such as *72 – IT services* instead of a very specific code, or add countries. Runs with 0 results cost nothing.

**I typed "AT" / "Österreich" / "Austria". Is that OK?** Yes. Names (English, German or local) and 2- or 3-letter codes are all understood. If a country cannot be recognised, the run stops with a message telling you what to fix (all input problems at once, e.g. a wrong country and a wrong date), and nothing is charged.

**My keyword found too much.** A keyword searches the whole notice text. Combine it with a sector, or use a more specific phrase such as `facility management`.

**Why is the deadline missing on some notices?** Not every notice has one (award notices, for example). `deadlineType` tells you whether a date is for submitting a tender or for a request to participate.

**Why is the estimated value empty?** Many buyers do not publish it. If you set *Minimum estimated value*, notices without a value are skipped (and free).

**How do I get only tenders I haven't seen yet?** Switch on *Only new notices since my last run* and schedule the Actor daily. If you run several different searches, give each its own *Alert name*.

**What happens with odd input?** Extra spaces, lower/upper case, commas, CPV codes with check digit (`72000000-8`) and German dates are cleaned up automatically. Anything that cannot be understood stops the run with a plain-English message before anything is charged.

**Is this legal to use commercially?** Yes. TED data is official EU open data, and reuse (including commercial reuse) is allowed under Commission Decision 2011/833/EU with attribution.

**How fresh is the data?** TED publishes about 2,500 notices every working day. Each run queries the live TED API.

**Which countries are covered?** All EU/EEA countries and some others that publish on TED.

### Limits

- The data is only as good as what buyers publish. Estimated value and deadline are often missing.
- TED covers tenders **above EU thresholds** (plus some voluntary ones). Smaller national tenders are published only on national portals.
- Max 15,000 notices per run (TED API limit). Narrow the dates or filters if you need more.
- If the TED API is down, the run stops with a clear message and nothing is charged.

### Data source and licence

Uses the **official TED Search API v3** (no website scraping, no login). Source: TED – Tenders Electronic Daily, © European Union. Reuse is permitted under Commission Decision 2011/833/EU. Every row carries a `source` attribution. This Actor is not affiliated with the EU Publications Office.

### Related tools from Alpine Data Labs

- [Crypto Arbitrage Scanner](https://apify.com/alpine-data/crypto-spread-scanner): exchange spreads for one coin on 20 exchanges, net of fees, as Excel.
- [Honeypot & Rug Pull Checker](https://apify.com/alpine-data/token-risk-scanner): token risk score (0-100) and honeypot/rug pull flags for Ethereum, BSC, Base and Solana.
- [Zefix Scraper: Swiss Company Register](https://apify.com/alpine-data/swiss-company-register): Swiss company lists with UID, legal form and address (Handelsregister Schweiz).
- [Career Page Job Scraper](https://apify.com/alpine-data/career-site-jobs): every open job from Greenhouse, Lever, Workday, Ashby and Personio, plus hiring signals.
- [All tools from Alpine Data Labs](https://apify.com/alpine-data): no-code data tools for public data, business research and monitoring.

### For developers: API & integrations

Everything in the form is also available via the API, with the same field names. Old inputs keep working; new fields are optional.

**Input JSON example**

```json
{
  "countries": ["AUT", "DEU"],
  "cpvCodes": ["72000000"],
  "keywords": ["Software", "Cloud"],
  "daysBack": 7,
  "maxResults": 200,
  "onlyNew": true,
  "stateKey": "it-dach",
  "onlyOpen": true
}
```

The API is forgiving too: `"countries": ["Austria", "de"]`, `"cpvCodes": ["72000000-8"]` or `"publishedFrom": "01.10.2026"` work as well.

**cURL** (run and get the results in one call):

```bash
curl -X POST "https://api.apify.com/v2/acts/alpine-data~ted-tender-monitor/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"countries": ["AUT"]}'
```

**JavaScript** (`npm i apify-client`):

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('alpine-data/ted-tender-monitor').call({"countries": ["AUT"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("alpine-data/ted-tender-monitor").call(run_input={"countries": ["AUT"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

**Webhooks, schedules and no-code tools:** add a webhook (event *Run succeeded*) in the *Integrations* tab to call your own URL when a run finishes, or use the official Apify apps for **Make, Zapier and n8n** (action *Run Actor*, then *Get dataset items*). Schedules work for API users too. AI agents can call this Actor via the **Apify MCP server** (mcp.apify.com).

### Support

Found a bug, need a field or another filter? Open an issue in the **Issues** tab of this Actor page. Alpine Data Labs answers there, usually within one working day.

Built and maintained by **Alpine Data Labs**.

# Actor input Schema

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

Pick one or more countries where the public buyer is located. Example: Austria + Germany. Choose 'All countries' for the whole EU/EEA. If you leave the field empty, Austria + Germany is searched (the run log says so). You can also type names or codes such as Österreich, AT or AUT.

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

Pick the kind of work or product (EU 'CPV' categories). A main category includes all its sub-categories, e.g. '72 IT services' also finds software development and hosting. Leave empty for all sectors. You can also type a CPV code such as 90910000 or a word such as Reinigung.

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

Finds notices that mention ANY of these words anywhere in the text, in any language. Example: Software, Cloud, Reinigung. One word or phrase per line (commas also work).

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

How far back to look. Example: 7 = notices published in the last week. For a daily alert use 1 or 2 together with 'Only new notices'.

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

The run stops after this many notices, so you never pay more than you expect. Example: 200 notices cost at most $0.60 ($0.003 each).

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

Remembers which notices you already got (in a storage in your own Apify account) and skips them next time. Skipped notices are free. Example: schedule daily at 07:00 = a free-of-subscription tender alert.

## `stateKey` (type: `string`):

Optional. Give each saved search its own name so their 'already seen' lists stay separate. Example: vienna-it. Leave empty if you only have one alert.

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

Which kinds of notices to return. Example: 'Open calls for tender' = tenders you can still bid on; 'Contract award notices' = who won and for how much.

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

Skips notices whose deadline has already passed. Notices without a deadline are kept. Skipped notices are free. Example: switch on if you only want tenders you can still bid on.

## `minEstimatedValue` (type: `integer`):

Optional. Keeps only notices whose published estimated value is at least this amount (in the notice currency, usually EUR). Example: 100000. Notices without a published value are skipped (and free).

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

Optional. Use an exact start date instead of 'last … days'. Example: 2026-10-01 (01.10.2026 also works).

## `preferredLanguages` (type: `array`):

Which language to use for the title, buyer name and the notice link when TED has several. Example: German, then English. An English title is always included as well.

## Actor input object example

```json
{
  "countries": [
    "AUT",
    "DEU"
  ],
  "cpvCodes": [
    "72000000"
  ],
  "keywords": [],
  "daysBack": 7,
  "maxResults": 200,
  "onlyNew": false,
  "noticeTypes": [
    "contract_notices"
  ],
  "onlyOpen": false,
  "preferredLanguages": [
    "deu",
    "eng"
  ]
}
```

# Actor output Schema

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

One row per public tender: deadline, days left, title, buyer, city, country, estimated value, type, publication date and link. Open the 'All details' view for CPV codes, procedure, PDF link and more.

# 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": [
        "AUT",
        "DEU"
    ],
    "cpvCodes": [
        "72000000"
    ],
    "keywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("alpine-data/ted-tender-monitor").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": [
        "AUT",
        "DEU",
    ],
    "cpvCodes": ["72000000"],
    "keywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("alpine-data/ted-tender-monitor").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": [
    "AUT",
    "DEU"
  ],
  "cpvCodes": [
    "72000000"
  ],
  "keywords": []
}' |
apify call alpine-data/ted-tender-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,alpine-data/ted-tender-monitor"
        }
    }
}
```

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/vdp5vWmfmunLZymdc/builds/yZ59NH3thLnL1SNNX/openapi.json
