# EU Public Procurement Contract Awards (TED) — value vs estimate (`eudatafeeds/eu-contract-awards-ted`) Actor

Awarded EU public procurement contracts from TED: one flat JSON row per contract award notice with the awarded value, the pre-tender estimate and the ratio between them, by buyer country and CPV. No winner names.

- **URL**: https://apify.com/eudatafeeds/eu-contract-awards-ted.md
- **Developed by:** [EU Data Feeds](https://apify.com/eudatafeeds) (community)
- **Categories:** Business, Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 award returneds

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

Every public contract award above the EU thresholds is published on **TED** (Tenders Electronic Daily),
the official EU public procurement journal. The official API returns an eForms tree: multilingual
arrays, the awarded value in one field, the pre-tender estimate in another, currencies in two more, and
personal data mixed into the contact blocks. This Actor turns TED into one flat row per contract award —
with the arithmetic already done.

Its sibling Actor, **EU Public Procurement Notices (TED)**, answers "what is open right now".
**This one answers "what was actually bought, from where, and for how much against the estimate."**

### Who buys this

- **Bid teams** benchmarking prices before they quote on a public tender.
- **Market analysts** sizing public spend by CPV division, buyer country or year.
- **Procurement and GovTech products** that need an EU contract-award feed without an eForms parser.
- **Researchers** studying how far EU procurement awards land from their pre-tender estimates.

### Coverage (measured, not claimed)

A 1,000-award sample of the last 30 days, taken 2026-09-05, carried buyers from **all 27 EU member
states** plus Norway, Iceland, Switzerland, Moldova and North Macedonia — 32 countries in one month's
window. In that same sample **919 of 1,000 awards carried a published awarded value**, and **428 carried
both an awarded value and a pre-tender estimate in the same currency**, which is when the ratio is
computed. Where TED has no number, the field is `null` — never a guess.

### What you get

One row per award notice:

| Field | Example |
|---|---|
| `publicationNumber` | `00612345-2026` |
| `publicationDate` | `2026-09-02+02:00` |
| `noticeType` / `formType` / `procedureType` | `can-standard` / `result` / `open` |
| `title` | `Supply of laboratory equipment` |
| `buyerName` / `buyerCountry` / `buyerCity` | `Univerzita Karlova` / `CZE` / `Praha` |
| `cpvCodes` / `cpvDivision` | `["38000000","38900000"]` / `38` |
| `awardedValue` / `awardedCurrency` | `1180000` / `CZK` |
| `estimatedValue` / `estimatedCurrency` | `1250000` / `CZK` |
| `awardedToEstimatedRatio` | `0.944` |
| `winnerCountry` / `crossBorderAward` | `DEU` / `true` |
| `placeOfPerformance` | `["CZ010"]` |
| `noticeUrl` | link to the official notice |

Every run also writes a `RUN_SUMMARY` record to the key-value store: award count, counts by buyer country
and CPV division, total awarded value **grouped by currency**, and the median awarded/estimated ratio.

### Input

| Option | Meaning |
|---|---|
| `days` | Lookback window, 1–365. Default 30. |
| `cpv` | CPV codes or prefixes — `72000000` for IT services, or just `45` for all construction. |
| `countries` | Buyer country codes: `CZ`, `DE`, `PL`, … |
| `awardTypes` | Award notice types. Default `can-standard`. |
| `minAwardedValue` | Only awards at or above this value, in the notice's own currency. |
| `maxResults` | Hard cap on rows returned — and therefore on what you pay. |

Leave everything empty and you get the last 30 days of EU public procurement contract awards.

### Running it on a schedule

Set `days` to match your interval, add your CPV codes and buyer countries, and put the Actor on an Apify
schedule. Each run writes a dataset you can pull from the Apify API, export as JSON/CSV/Excel, or push
onward with an integration; `RUN_SUMMARY` gives you the aggregates without reading every row.

### Two things this Actor deliberately does not do

- **No currency conversion.** Values stay in the currency TED published them in, and the
  awarded/estimated ratio is computed **only** when both figures share a currency. A single mixed
  EUR+HUF total would be a made-up number, so you get sums grouped by currency instead.
- **No winner names.** See below.

### Personal data

TED award notices contain named contact persons, and the "winning company" can be a sole trader — a
natural person. **This Actor never requests or emits winner names, winner identifiers or winner addresses**;
only the winner's country code, which identifies nobody. Contact names, e-mail addresses and phone
numbers are dropped in code before anything is written to the dataset, and free-text fields are scrubbed
for inlined addresses. You get organisations and countries, not people. The open-data licence permits
reuse; it does not waive the GDPR, so the personal data simply never leaves the pipeline.

If you need the winner's legal name, use the official notice at `noticeUrl` — it is public there, under
the Publications Office as controller, not under us.

### Pricing

Pay per event, and both numbers are here so you never have to open the Pricing tab to budget a run:

| Event | Price | When it fires |
|---|---|---|
| Actor start | $0.005 | Once per run, never more. |
| Award returned | $0.002 | Once per contract award actually pushed to the dataset. |

A default run (`maxResults: 100`) therefore costs **$0.005 + 100 x $0.002 = $0.205** at most. `maxResults`
is a hard cap on rows and so is your hard cap on spend: 500 awards is $1.005, 5,000 is $10.005.

A run that finds nothing costs $0.005 — the start event only. Charging happens **after** each row is
pushed, so a run that fails halfway never bills you for data you did not receive, and the `RUN_SUMMARY`
record written at the end tells you exactly how many rows you were charged for.

### Source and attribution

Source: Tenders Electronic Daily (TED), ted.europa.eu, © European Union. Editorial content reused under
CC BY 4.0, metadata under CC0 1.0. Data normalized, enriched and filtered by this Actor; personal data
removed. **This is not an official EU publication** — for anything legally binding, use the linked
original notice.

### Support and refunds

E-mail support, first reply within 1 business day. Not happy? Email us within 14 days for a full refund.

### Limits

- Coverage and freshness are whatever TED publishes; if an award is not in TED, it is not here.
- Below-threshold contracts that never reach TED are out of scope — national portals are not read.
- Not every award notice carries a published value or a pre-tender estimate. See the measured numbers in
  the coverage section above; where TED has no number, the field is `null` and the ratio is `null`.
- Very large windows across all of the EU take longer and cost more — narrow by CPV or country first.
- No human consulting, no custom fields on request, no SLA beyond the reply time above.

### FAQ

**Does this cover all 27 EU member states?** Yes — see the measured coverage above. TED is the single
EU-wide publication point for above-threshold public procurement.

**How is this different from the notices Actor?** Notices are tenders that are open for bidding. Awards
are the result: who bought, in which country, at what value against the estimate.

**Why is `awardedToEstimatedRatio` sometimes null?** Because TED published only one of the two figures,
or published them in different currencies. Inventing the missing half would be a made-up number.

**Do I get the winner's company name?** No — only the winner's country code. The official notice at
`noticeUrl` carries the legal name, published by the EU Publications Office.

# Actor input Schema

## `days` (type: `integer`):

How far back to search, counted from today. 1-365. Awards are published in bursts, so 30 days is a more useful default than a week.

## `cpv` (type: `array`):

CPV codes or prefixes, e.g. 72000000 for IT services or just 45 for construction. Empty = all sectors.

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

Countries of the contracting authority. Two-letter (CZ, DE, PL) or TED's three-letter (CZE, DEU, POL) codes both work. An unknown code fails the run instead of being ignored. Empty = all countries.

## `awardTypes` (type: `array`):

TED notice types treated as awards. Default is cn-standard's counterpart can-standard (contract award notice). Leave as is unless you know you need another award form.

## `minAwardedValue` (type: `integer`):

Only awards with a published total value at or above this amount, in the notice's own currency. Awards without a published value are excluded when this is set.

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

Upper bound on rows returned. You are charged per award returned, so this is also your cost cap.

## Actor input object example

```json
{
  "days": 30,
  "cpv": [
    "72000000"
  ],
  "countries": [
    "CZ"
  ],
  "awardTypes": [
    "can-standard"
  ],
  "maxResults": 100
}
```

# Actor output Schema

## `awards` (type: `string`):

All award notices returned by this run, one row each. Field definitions are in the dataset schema.

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

Row count, the TED attribution line and confirmation that personal data was removed.

# 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 = {
    "cpv": [
        "72000000"
    ],
    "countries": [
        "CZ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("eudatafeeds/eu-contract-awards-ted").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 = {
    "cpv": ["72000000"],
    "countries": ["CZ"],
}

# Run the Actor and wait for it to finish
run = client.actor("eudatafeeds/eu-contract-awards-ted").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 '{
  "cpv": [
    "72000000"
  ],
  "countries": [
    "CZ"
  ]
}' |
apify call eudatafeeds/eu-contract-awards-ted --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eudatafeeds/eu-contract-awards-ted"
        }
    }
}

```

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/zrBa6AAltkIcHcnWf/builds/KeZ6mJLzqpEl060Ai/openapi.json
