# EU Tenders Scraper (TED) & UK Find a Tender Bid Alerts (`studded_columbine/eu-ted-uk-tenders-scraper`) Actor

Export EU public tenders and contract awards from TED (Tenders Electronic Daily), plus optional UK Find a Tender notices. Filter by keyword, CPV code, country, NUTS region, deadline and value. Daily new-tender alerts. Official APIs, no key needed. CSV, Excel, JSON.

- **URL**: https://apify.com/studded_columbine/eu-ted-uk-tenders-scraper.md
- **Developed by:** [Tenderly Data](https://apify.com/studded_columbine) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

### What does EU Tenders Scraper (TED) do?

**EU Tenders Scraper** exports **European public procurement notices from TED (Tenders Electronic Daily)**, the EU's official tender journal, into a spreadsheet or JSON. Find **open public tenders** across all EU and EEA countries by keyword, **CPV code**, buyer country, **NUTS region**, deadline and value, or pull **contract awards** with winners and awarded values. Optionally add **UK Find a Tender** notices in the same run. Turn on *Only new* and schedule it for **daily bid alerts**.

- Uses the **official TED Search API** and the **official Find a Tender OCDS API**, not page scraping, so data is structured and stable. No API key or TED account needed.
- One flat row per notice: title (translated to English or your language), buyer, contact email, CPV codes, place of performance, deadline, days left, estimated value, winners, links to documents and the bid submission page.
- **Pay per notice:** no subscription, you only pay for notices returned (see pricing below).
- Export to **CSV, Excel, JSON, XML or HTML**, or push to Google Sheets, Slack, email, Zapier or Make with Apify integrations and the Apify API.

### Who is this TED tender scraper for?

- **Companies bidding for public contracts** in the EU and UK: IT and software, construction, consulting, medical supplies, facility services, translation, training.
- **Bid and tender consultants** who monitor tenders for several clients and need a daily list per client.
- **Sales teams** who want to know which public bodies are buying what, and who won past contracts (awards view).
- **Market researchers and journalists** analysing public spending by sector, country or buyer.

### How to get EU public tenders from TED

1. Click **Try for free**. The form is prefilled with keyword "software", buyer countries DE, FR, NL and IE, open tenders published in the last 7 days, 25 results.
2. Change the **Keywords** and/or **CPV codes** (prefixes work: `72` = IT services, `45` = construction work), and the **Buyer countries** (`DE`, `FR`, `PL`…), or leave countries empty for all of Europe.
3. Optionally tick **Only tenders still open**, set a **Minimum value**, or a **Place of performance** NUTS region.
4. Add **UK – Find a Tender** under *Sources* to include UK notices.
5. Click **Start**. Results appear in the **Tenders** view; switch to **Bid details** (contacts, documents, submission link) or **Awards** (winners and values).
6. **For daily bid alerts:** turn on *Only notices not returned before*, set a *State key* (e.g. `it-tenders-dach`), and schedule the Actor daily. Each run returns only notices you haven't received yet.

### Input examples

Open IT tenders in Germany, Austria and Switzerland still accepting bids:

```json
{ "sources": ["ted"], "cpvCodes": ["72", "48"], "countries": ["DE", "AT", "CH"], "onlyOpen": true, "publishedWithinDays": 14, "maxResults": 200 }
```

Daily alert for construction tenders over €1M in Ireland and the UK:

```json
{ "sources": ["ted", "uk-fts"], "cpvCodes": ["45"], "countries": ["IE", "GB"], "minValue": 1000000, "publishedWithinDays": 2, "onlyNew": true, "stateKey": "construction-ie-uk", "maxResults": 0 }
```

Contract awards for cybersecurity in the last 90 days, with winners:

```json
{ "noticeTypes": ["result"], "keywords": ["cyber security", "penetration testing"], "publishedWithinDays": 90, "maxResults": 500 }
```

### Filters

| Filter | TED | UK Find a Tender |
|---|---|---|
| Keywords (any of) | Full-text search of the notice, all languages | Title, description, buyer name |
| CPV codes / prefixes | ✓ (sub-codes included) | ✓ |
| Buyer countries | ✓ | UK only (`GB`) |
| Place of performance (NUTS) | ✓ | ✓ (UK ITL codes such as `UKI`) |
| Notice types | ✓ | ✓ (open tenders, planning, awards, changes, modifications) |
| Published date range | ✓ | ✓ |
| Only still open (deadline ≥ today) | ✓ | ✓ |
| Min / max value | ✓ | ✓ |
| Buyer name contains | ✓ | ✓ |
| TED expert query | ✓ | – |

### Output: TED tender data fields

| Field | Example |
|---|---|
| `source` | `TED` or `UK-FTS` |
| `noticeId`, `noticeUrl`, `pdfUrl` | `729959-2026`, `https://ted.europa.eu/en/notice/-/detail/729959-2026` |
| `noticeType`, `noticeSubtype` | `competition`, `cn-standard` |
| `title`, `originalTitle`, `description` | `Germany – Software package and information systems – Beschaffung …` |
| `contractNature`, `procedureType` | `supplies`, `open` |
| `publicationDate`, `tenderDeadline`, `requestToParticipateDeadline`, `daysUntilDeadline` | `2026-10-21`, `2026-11-20T10:00:00+01:00`, `30` |
| `buyerName`, `buyerCountry`, `buyerCity`, `buyerEmail`, `buyerWebsite`, `buyerType` | `Universität Stuttgart`, `DE`, `Stuttgart`, … |
| `mainCpv`, `cpvCodes`, `placeOfPerformance` | `48000000`, `["48000000","72000000"]`, `["DE111"]` |
| `estimatedValue`, `value`, `awardedValue`, `currency` | `384000`, `EUR` |
| `winners`, `winnerCountries` | `["Kempen Krause Ingenieure GmbH"]`, `["DE"]` |
| `documentsUrl`, `submissionUrl` | links to the procurement documents and e-submission page |
| `procedureId` | links all notices (tender, changes, award) of one procurement |

The run summary (`OUTPUT` in the key-value store) shows the exact TED query used, total matches, notices per source and already-seen notices skipped.

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

Pay per event: **US$0.002 per notice** (US$2 per 1,000) plus **US$0.01 per run**. A daily alert that finds 20 new tenders costs about US$0.05. The prefilled "Try for free" run (25 notices) costs about US$0.06. Set **Max cost per run** in the run options to cap spending; the Actor stops cleanly at that limit.

### Tips for better TED searches

- TED titles are machine-translated into all EU languages, so English keywords match most notices. For precise targeting, combine a **CPV prefix** with a country.
- Use **Only tenders still open** for bid alerts and **Contract awards** for competitor and pricing research.
- Values are in each notice's own currency (mostly EUR; also PLN, SEK, CZK, GBP…). Many notices don't publish a value; a value filter excludes those.
- UK Find a Tender has a strict API rate limit (about 100 notices per 11 seconds), so prefer short date ranges for UK, e.g. a daily alert.

### Data source and limitations

TED data comes from the [TED Search API](https://docs.ted.europa.eu/api/latest/search.html) of the Publications Office of the European Union and is reused under the [TED legal notice](https://ted.europa.eu/en/legal-notice) (free reuse with source acknowledged). Source: TED, © European Union. UK data comes from the [Find a Tender OCDS API](https://www.find-tender.service.gov.uk/Developer/Documentation) under the Open Government Licence v3.0. This Actor is not affiliated with the EU or the UK Government. TED covers tenders above EU thresholds plus those published voluntarily; many smaller national tenders appear only on national portals.

### FAQ

#### Do I need a TED account or API key?

No. Both official APIs are open for published notices.

#### How is this different from the TED website search?

The TED website is built for browsing. This Actor runs your saved search on a schedule, returns only new notices, flattens multi-lot notices into one row with the earliest deadline, adds days-to-deadline, and exports to CSV/Excel or your tools. It also adds UK Find a Tender in the same dataset.

#### Can I get TED tender alerts by email or Slack?

Yes. Schedule the Actor daily with *Only new* on, then add an Apify integration (email, Slack, Google Sheets, Zapier, Make or a webhook).

#### Can I get historical notices?

Yes. Set *Published from* / *Published to* to any range; TED holds notices going back many years.

#### Can I use it from Python, JavaScript or an AI agent?

Yes. Use the Apify API or client libraries (see the **API** tab), or the Apify MCP server so AI assistants can call it as a tool.

### More from Tenderly Data

- [SAM.gov Scraper](https://apify.com/studded_columbine/samgov-contract-opportunities): U.S. federal contract opportunities and daily bid alerts.
- [UK Companies House Scraper](https://apify.com/studded_columbine/uk-companies-house-scraper): new UK companies, directors and owners.

# Actor input Schema

## `sources` (type: `array`):

<b>TED</b>: all EU/EEA public procurement notices above EU thresholds (official TED Search API). <b>UK Find a Tender</b>: UK public procurement notices (official OCDS API; slower, about 100 notices per 11 seconds because of its rate limit).

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

Default: open tenders (contract notices) only. Add 'Contract awards' for award winners and values.

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

Any of these words or phrases (OR). TED searches the full notice text in all EU languages (titles are machine-translated, so English keywords work for most notices). UK: matched in title, description and buyer name.

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

CPV codes or prefixes; sub-codes are included. "72" = all IT services, "48" = software packages, "45" = construction work, "79" = business services, "33" = medical equipment.

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

ISO country codes of the buying organisation, 2 or 3 letters ("DE", "FR", "PL", "NL", "IE"). Leave empty for all. Include "GB" if you also use UK Find a Tender.

## `placeOfPerformance` (type: `array`):

NUTS region codes, sub-regions included: "FR1" = Île-de-France, "DE21" = Oberbayern, "IE06", "UKI" = London.

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

1 = today only. Overrides 'Published from'. Default when no dates are set: last 7 days.

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

YYYY-MM-DD

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

YYYY-MM-DD

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

Only notices whose tender (or request-to-participate) deadline is today or later. Notices without a deadline are excluded.

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

Total / estimated value in the notice's own currency (mostly EUR). Notices without a value are excluded when set.

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

Same currency caveat as minimum value.

## `buyerNameIncludes` (type: `string`):

e.g. "Bundesagentur", "NHS", "University".

## `expertQuery` (type: `string`):

Optional raw TED expert-search query, ANDed with the filters above (TED only). Example: <code>procedure-type IN (open) AND contract-nature-main-proc IN (services)</code>. See the TED expert search help.

## `language` (type: `string`):

Language for the translated TED title and buyer name (falls back to English, then the original).

## `sortBy` (type: `string`):

Newest notices first (best with a max results limit) or oldest first. UK Find a Tender is always newest first.

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

Maximum notices to return from each source. 0 = no limit.

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

Remembers which notices this saved search already returned (per 'State key') and returns only new ones. Schedule it daily for bid alerts.

## `firstRunBehavior` (type: `string`):

'Return all' delivers current matches on the first run; 'Baseline only' silently records them (no charge per notice) so later runs return only notices published after today.

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

Name for this alert's memory. Defaults to a hash of the filters. Use different keys for different alerts.

## `ukMaxPages` (type: `integer`):

Find a Tender filters only by date on its side, so this Actor scans pages of 100 notices (about 475 per day) at about 11 s per page. Stops after this many pages.

## Actor input object example

```json
{
  "sources": [
    "ted"
  ],
  "noticeTypes": [
    "competition"
  ],
  "keywords": [
    "software"
  ],
  "countries": [
    "DE",
    "FR",
    "NL",
    "IE"
  ],
  "publishedWithinDays": 7,
  "onlyOpen": false,
  "language": "eng",
  "sortBy": "newest",
  "maxResults": 25,
  "onlyNew": false,
  "firstRunBehavior": "returnAll",
  "ukMaxPages": 60
}
```

# Actor output Schema

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

All notices returned by this run (default dataset). Switch to the 'Bid details' or 'Awards' views for other columns.

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

JSON summary: notices pushed per source, total TED matches, the TED query used, UK notices scanned, already-seen notices skipped, API request stats and filters.

# 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 = {
    "sources": [
        "ted"
    ],
    "keywords": [
        "software"
    ],
    "countries": [
        "DE",
        "FR",
        "NL",
        "IE"
    ],
    "publishedWithinDays": 7,
    "maxResults": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("studded_columbine/eu-ted-uk-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 = {
    "sources": ["ted"],
    "keywords": ["software"],
    "countries": [
        "DE",
        "FR",
        "NL",
        "IE",
    ],
    "publishedWithinDays": 7,
    "maxResults": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("studded_columbine/eu-ted-uk-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 '{
  "sources": [
    "ted"
  ],
  "keywords": [
    "software"
  ],
  "countries": [
    "DE",
    "FR",
    "NL",
    "IE"
  ],
  "publishedWithinDays": 7,
  "maxResults": 25
}' |
apify call studded_columbine/eu-ted-uk-tenders-scraper --silent --output-dataset

```

## MCP server setup

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