# EU Tender Radar: TED Tenders & Competition Data (`doodlebyte/eu-tender-radar`) Actor

Monitor EU public tenders from TED and see how winnable each one is: how many bids this buyer's similar contracts get, how often only one company bids, who usually wins, and award prices against estimates. Pay per tender, no subscription.

- **URL**: https://apify.com/doodlebyte/eu-tender-radar.md
- **Developed by:** [Aditya](https://apify.com/doodlebyte) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 tender delivereds

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

## EU Tender Radar: TED Tenders & Competition Data

Find EU public tenders you can actually win. EU Tender Radar monitors
**TED** (Tenders Electronic Daily, the EU's official procurement journal,
about 3,500 notices a day). It delivers the new tenders that match what you
sell. Each one comes with its **competition history**:

- **Typical number of bids:** how many tenders this buyer's similar
  contracts received.
- **Single-bid share:** how often only one company took part. Across the
  EU, about a third of awarded contracts got just one bid. That share is
  about 41% in Poland and 15–16% in Germany and France.
- **Usual winner:** who won this buyer's contracts in the same category.
- **Award price against estimate:** how far below the buyer's estimate the
  contracts went.

On TED's free website, you get this only by opening past award notices
one by one. Tender platforms bundle it into subscriptions of €125–500 a
month. Here you pay per tender, and only for what is delivered.

### Who it is for

- **Companies selling to the public sector** (IT, construction, medical,
  consulting, facilities) that want a daily feed of relevant tenders in
  their sheet, CRM or Slack.
- **Bid managers and consultants** deciding which tenders are worth the
  effort of a bid.
- **Market analysts** studying who wins public contracts, at what prices
  and against how much competition (awards mode).

### How to use

1. Describe what you sell:
   - **CPV codes** (for example `72` for IT services, `45` for
     construction, `33` for medical equipment);
   - **keywords** in any language;
   - **countries**.
2. Optionally set a minimum value and the minimum number of days left to
   bid.
3. For monitoring, turn on **Only new notices** and schedule the Actor
   daily. Each tender is delivered and charged once.
4. Connect the dataset to Google Sheets, Slack, email, Make, Zapier or
   n8n through Apify integrations, or call it through the API.

To see the output first, start a run with no filters. It delivers a sample
of the 20 newest tenders EU-wide. An invalid CPV code or country is
skipped with a warning; it does not stop the run.

### Output

One item per tender:

```json
{
  "publicationNumber": "711286-2026",
  "url": "https://ted.europa.eu/en/notice/-/detail/711286-2026",
  "publicationDate": "2026-10-15",
  "title": "dostawa, przedłużenie, aktualizacja oraz wsparcie dla licencji…",
  "category": "Software package and information systems",
  "buyerName": "Ośrodek Przetwarzania Informacji – Państwowy Instytut Badawczy",
  "buyerCountry": "PL",
  "buyerCity": "Warszawa",
  "cpvMain": "48000000",
  "estimatedValue": 400000,
  "currency": "PLN",
  "estimatedValueEur": 94118,
  "deadline": "2026-11-28",
  "daysToDeadline": 34,
  "lots": 3,
  "procedureType": "open",
  "documentsUrl": "https://…",
  "competitionLevel": "low",
  "typicalTenders": 1,
  "singleBidShare": 0.67,
  "likelyIncumbent": "…",
  "competition": {
    "basis": "buyer-category",
    "buyerInCategory": { "awards": 3, "medianTenders": 1, "singleBidShare": 0.67, "medianAwardToEstimate": 0.9, "topWinners": [{ "name": "…", "wins": 2 }] },
    "buyer": { "awards": 41, "…": "…" },
    "market": { "cpvDivision": "48000000", "country": "PL", "awards": 1000, "medianTenders": 2, "…": "…" }
  }
}
```

- **`competitionLevel`:** typical bids per lot of 2 or fewer is `low`, up
  to 5 is `medium`, and more is `high`.
- **`basis`:** which history it is based on:
  1. the buyer in this CPV division;
  2. if that has too little data, the buyer overall;
  3. otherwise the market (CPV division in the buyer's country).

**Awards mode** returns one item per contract award notice instead: winners,
tenders received per lot, awarded value (also in EUR), estimate and
award-to-estimate ratio.

### Pricing

Pay per event. Platform usage is included, and there is no subscription.
Higher Apify discount tiers pay less:

| Event | Free and Bronze | Silver | Gold and above |
|---|---|---|---|
| Tender delivered | $0.004 | $0.0035 | $0.003 |
| Competition insight (per tender, optional; charged only when past awards are found) | $0.006 | $0.005 | $0.0045 |
| Award delivered (awards mode) | $0.003 | $0.0025 | $0.002 |
| Actor start (charged by Apify once per run, per GB of memory) | $0.00005 | $0.00005 | $0.00005 |

**Example:** 20 new tenders a day with insights costs about $6 a month.

### Data and coverage

- **Source:** TED Search API, the official, open EU data service, reused
  with attribution under the EU's open data policy. Notices © European
  Union, https://ted.europa.eu.
- **Coverage:** TED holds all tenders above the EU thresholds from the 27
  EU countries, plus EEA and other European countries, and some notices
  below the thresholds. Many smaller national tenders are published only on
  national portals and are not included yet.
- **Insight data:** competition insights use award notices of the last 36
  months (configurable). About 80–85% of recent award notices state how
  many tenders were received.
- **Privacy:** no contact persons, emails or phone numbers are collected.
  Buyers and winners are organisations, as published on TED.

### Limits

- **Statistics, not predictions:** competition insights describe past
  awards. They do not predict who will bid next time.
- **Language:** titles and descriptions are in the notice's original
  language. TED's English category label is given in `category`.
- **Values:** values in other currencies are converted with the ECB's daily
  reference rates. Framework agreements often state ceilings, not expected
  spend.
- **Support:** report problems in the Issues tab. Fixes ship as new Actor
  versions.

# Actor input Schema

## `mode` (type: `string`):

Open tenders you can bid for, or past contract awards for market and competitor analysis.

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

Full-text search terms (any language TED holds). A notice matches if it contains any of them.

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

Common Procurement Vocabulary codes. A prefix selects its whole branch: 72 = all IT services, 4521 = building construction. Find codes at simap.ted.europa.eu.

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

Countries of the contracting authority. Empty means all countries on TED.

## `publishedWithinDays` (type: `integer`):

How far back to look. For daily monitoring, 3 days with 'Only new notices' on is enough.

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

Remember delivered notices and skip them in later runs of the same search, so a daily schedule delivers (and charges) each notice once.

## `minValueEur` (type: `integer`):

Skip tenders whose estimated value is below this. Tenders without a published value are kept.

## `minDaysToDeadline` (type: `integer`):

Skip tenders whose submission deadline is sooner than this.

## `includeExpired` (type: `boolean`):

Also return tenders whose deadline has passed, for example to study past calls. By default they are skipped.

## `includePlanning` (type: `boolean`):

Also return planned procurements announced before the call for competition.

## `competitionInsights` (type: `boolean`):

For each open tender: how many bids this buyer's similar contracts received, how often only one bidder took part, the usual winners, and awarded value against estimate, from TED award notices.

## `historyMonths` (type: `integer`):

How many months of past awards to analyse.

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

Stop after this many notices. With no filter set, a run delivers a sample of at most 20.

## Actor input object example

```json
{
  "mode": "tenders",
  "keywords": [],
  "cpvCodes": [
    "72"
  ],
  "countries": [
    "DE"
  ],
  "publishedWithinDays": 7,
  "onlyNew": false,
  "minDaysToDeadline": 0,
  "includeExpired": false,
  "includePlanning": false,
  "competitionInsights": true,
  "historyMonths": 36,
  "maxItems": 20
}
```

# Actor output Schema

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

Default dataset: one item per open tender (tenders mode, with competition insights when enabled) or one item per contract award notice (awards mode). Every field is defined in the dataset schema; the 'tenders' and 'awards' views show the main fields of each mode.

## `runSummary` (type: `string`):

Record OUTPUT in the default key-value store, a JSON object with `mode` (tenders or awards), `matchingNoticesOnTed` (notices matching the filters on TED), `delivered` (items saved to the dataset in this run), `skippedAlreadyDelivered` (notices skipped because an earlier run delivered them, with 'Only new notices') `stoppedAtSpendingLimit` (true if the run stopped at the user's spending limit) and `inputWarnings` (how the input was adjusted, for example a skipped invalid CPV code or a no-filter sample; empty when none).

# 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": [],
    "cpvCodes": [
        "72"
    ],
    "countries": [
        "DE"
    ],
    "publishedWithinDays": 7,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("doodlebyte/eu-tender-radar").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": [],
    "cpvCodes": ["72"],
    "countries": ["DE"],
    "publishedWithinDays": 7,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("doodlebyte/eu-tender-radar").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": [],
  "cpvCodes": [
    "72"
  ],
  "countries": [
    "DE"
  ],
  "publishedWithinDays": 7,
  "maxItems": 20
}' |
apify call doodlebyte/eu-tender-radar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,doodlebyte/eu-tender-radar"
        }
    }
}
```

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/ubIPdoNYnZaaiMB6f/builds/VDJYFNSc9an3hY5Xt/openapi.json
