# Tender Award Monitor — who won EU (TED) + UK public contracts (`handa-labs/eu-tender-award-monitor`) Actor

Contract award notices from TED (EU) and UK Contracts Finder / Find a Tender: winner, buyer, value, tenders received, CPV — filtered by keyword, CPV and country, and only what is new since your last run. Official APIs, no scraping. For competitor tracking, subcontracting and sales.

- **URL**: https://apify.com/handa-labs/eu-tender-award-monitor.md
- **Developed by:** [tatsuya handa](https://apify.com/handa-labs) (community)
- **Categories:** Business, Lead generation, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 contract awards

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Tender Award Monitor — who won EU (TED) + UK public contracts

**See who is winning public contracts in your market — this week, not last year.** Filter contract award notices by keyword, CPV code and country, and get one clean record per award: **winner, buyer, value, number of bids, dates and links** — with only what is new since your last run.

### What you can do with it

- **Competitor tracking** — "Which IT vendors won German federal contracts this week, and for how much?"
- **Subcontracting** — a winner of a €5M framework needs partners now. Reach out the day the award is published.
- **Sales to buyers** — public bodies that just awarded a cloud migration will buy training, security and support next.
- **Market sizing** — sum disclosed award values by CPV and country over time.
- **AI agents** — schedule it and let an agent read the `llmSummary` of each award.

### Sample output

```json
{
  "type": "award",
  "change": "new",
  "publicationNumber": "600254-2026",
  "title": "Germany – IT services: consulting, software development, Internet and support – Entwicklung Intelligent Dispatching Agent (IDA)",
  "publicationDate": "2026-09-01",
  "buyerName": "Fraport AG",
  "buyerCountry": "DEU",
  "winnerName": "Reply Deutschland SE",
  "winners": ["Reply Deutschland SE"],
  "winnerCountry": "DEU",
  "winnerCity": "Gütersloh",
  "winnerSize": "large",
  "awardValue": 1250000,
  "currency": "EUR",
  "valueDisclosed": true,
  "tendersReceived": 9,
  "contractConclusionDate": "2026-08-24",
  "cpv": ["72000000", "72212131"],
  "procedureType": "open",
  "htmlUrl": "https://ted.europa.eu/en/notice/-/detail/600254-2026",
  "llmSummary": "Reply Deutschland SE (DEU) won \"Germany – IT services … (IDA)\" from Fraport AG (DEU), value 1250000 EUR, 9 tenders received. Published 2026-09-01. CPV 72000000/72212131."
}
```

Each run also emits a `summary` record with top winners, buyer countries and the sum of disclosed values.

### Fields

| Field | Meaning |
|---|---|
| `winnerName`, `winners` | winning supplier(s); several when a framework has multiple winners |
| `winnerCountry`, `winnerCity`, `winnerSize` | where the winner is based; size class (micro/small/medium/large) when published |
| `awardValue`, `currency`, `valueDisclosed` | award value; `null` / `false` when the buyer withheld it |
| `tendersReceived` | number of bids the buyer received (competition intensity) |
| `buyerName`, `buyerCountry`, `buyerCity`, `buyerEmail`, `buyerWebsite` | contracting authority |
| `contractConclusionDate`, `winnerDecisionDate` | when the contract was signed / decided |
| `cpv`, `contractNature`, `procedureType`, `placeOfPerformance` | classification |
| `htmlUrl`, `pdfUrl`, `xmlUrl` | the notice on TED / Contracts Finder / Find a Tender |
| `change` | `baseline` on the first run, `new` afterwards |

### Sources

- **TED (EU)** — contract award notices (`can-*`) via the official TED Search API v3.
- **UK Contracts Finder** — award-stage OCDS releases (public API, no key).
- **UK Find a Tender** — OCDS releases with active awards (public API, no key).

No scraping, no proxies, no login.

### Input

```json
{
  "keywords": ["cloud", "software"],
  "cpvCodes": ["72*"],
  "countries": ["DEU", "NLD", "GBR"],
  "winnerCountries": [],
  "minValue": 0,
  "daysBack": 7,
  "sinceLastRun": true
}
```

| Field | Default | Meaning |
|---|---|---|
| `keywords` | — | full-text terms, any match |
| `cpvCodes` | — | CPV codes, `*` prefix wildcard |
| `countries` | — | buyer countries (ISO alpha-3); GBR enables the UK sources |
| `winnerCountries` | — | only awards won by suppliers from these countries |
| `minValue` | 0 | only awards with a disclosed value ≥ this |
| `sources` | all | `ted`, `uk-contracts-finder`, `uk-find-a-tender` |
| `daysBack` | 7 | publication window |
| `sinceLastRun` | true | only awards not returned before for the same filters |
| `maxNotices` | 500 | cap per run |
| `includeDescription` | false | add procedure description text |

At least one of `keywords`, `cpvCodes`, `countries` is required.

### Monitor mode, watchlists and the free first run

All handa-labs monitors share the same controls:

| Field | Default | Meaning |
|---|---|---|
| `mode` | `monitor` | `monitor` remembers what was returned and emits only changes on later runs; `snapshot` returns everything matching on every run |
| `watchlistId` | `default` | label for this watchlist; runs with the same ID share memory, different IDs are independent |
| `emitBaseline` | `false` | the first monitor run establishes a **free baseline** (only the Actor-start fee) and returns counts; set `true` to also receive, and pay for, every current item on that first run |

Schedule the Actor with the same input and you get a clean change feed. Nothing is charged for records on the first run unless you ask for them.

### Pricing

Pay-per-event: a small fee per run plus a fee per award returned. With `sinceLastRun` on, a daily schedule on a focused query returns a handful of awards per day.

### Notes

- Some buyers withhold the value (`valueDisclosed: false`); the notice link still contains lots and framework details.
- Looking for calls for competition instead of awards? Use the companion **Public Tender Monitor** (EU TED + UK, new tenders since last run).

***

### 日本語

EU(TED)と英国の公共調達で「誰が・どこから・いくらで・何社と競って」落札したかを、キーワード×CPV×国で絞って返します。前回以降の新規だけを返すので、スケジュール実行すれば「今週の落札」がそのまま届きます。競合分析、下請け営業、発注者への次の提案に。公式APIのみ、スクレイピングなし。

# Actor input Schema

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

Words or phrases searched in the full text of the award notice (any language). Awards matching ANY keyword are returned. Leave empty to filter by CPV / country only.

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

Common Procurement Vocabulary codes; a trailing \* matches a prefix (72\* = IT services, 48\* = software, 45\* = construction, 79\* = business services, 85\* = health).

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

e.g. DEU, FRA, NLD, ESP, ITA, POL, SWE, BEL, AUT, IRL, GBR. Empty = all countries.

## `winnerCountries` (type: `array`):

Only awards won by suppliers from these countries (e.g. find foreign suppliers winning in your market). Empty = any.

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

"monitor" (default): remember what was returned and emit only changes on later runs. "snapshot": return everything matching, every run, no memory.

## `watchlistId` (type: `string`):

Label for this watchlist (e.g. "roofing-wa"). Runs with the same ID share memory; use different IDs for independent watchlists.

## `emitBaseline` (type: `boolean`):

The first monitor run establishes a free baseline and returns only counts. Turn this on to also receive (and pay for) every current item on that first run.

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

Only awards whose disclosed value is at least this amount (in the notice's currency). Awards without a disclosed value are excluded when this is set. 0 = no filter.

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

TED = EU contract award notices. UK sources = award-stage OCDS releases. UK sources are skipped automatically when the countries filter excludes GBR.

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

Only award notices published within the last N days.

## `sinceLastRun` (type: `boolean`):

Legacy switch. Prefer "mode". false = snapshot mode.

## `maxNotices` (type: `integer`):

Safety cap on the number of award notices fetched per run.

## `includeDescription` (type: `boolean`):

Adds up to 1,500 characters of the procedure description (original language).

## `stateStoreName` (type: `string`):

Named key-value store used to remember already-seen awards.

## Actor input object example

```json
{
  "keywords": [
    "cloud",
    "software"
  ],
  "cpvCodes": [
    "72*"
  ],
  "countries": [
    "DEU",
    "NLD",
    "GBR"
  ],
  "mode": "monitor",
  "watchlistId": "default",
  "emitBaseline": false,
  "minValue": 0,
  "sources": [
    "ted",
    "uk-contracts-finder",
    "uk-find-a-tender"
  ],
  "daysBack": 7,
  "sinceLastRun": true,
  "maxNotices": 500,
  "includeDescription": false,
  "stateStoreName": "tender-award-state"
}
```

# Actor output Schema

## `results` (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 = {
    "keywords": [
        "cloud",
        "software"
    ],
    "cpvCodes": [
        "72*"
    ],
    "countries": [
        "DEU",
        "NLD",
        "GBR"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("handa-labs/eu-tender-award-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 = {
    "keywords": [
        "cloud",
        "software",
    ],
    "cpvCodes": ["72*"],
    "countries": [
        "DEU",
        "NLD",
        "GBR",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("handa-labs/eu-tender-award-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 '{
  "keywords": [
    "cloud",
    "software"
  ],
  "cpvCodes": [
    "72*"
  ],
  "countries": [
    "DEU",
    "NLD",
    "GBR"
  ]
}' |
apify call handa-labs/eu-tender-award-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,handa-labs/eu-tender-award-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/CHBc9cqxlOurw0qjn/builds/kM0JyobTPrzdodIv9/openapi.json
