EU Contract Awards (TED): Clean, with Discount & Bids
Pricing
from $3.00 / 1,000 results
EU Contract Awards (TED): Clean, with Discount & Bids
Clean, dated, verifiable EU public-procurement award records from TED: buyer, winner, awarded vs estimated value, discount %, number of bids, CPV, dates. Framework agreements detected, outliers flagged. By ABoringBot.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Mirko Tornani
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
EU Public Contract Awards (TED) — Clean, Verified, with Discount & Bids
By ABoringBot. Who won which EU public contract, for how much, against how many bidders, and how far below the estimate. Every row is dated and links back to the official notice.
What problem does this solve?
TED (Tenders Electronic Daily) publishes every EU public-contract award above the threshold. The raw data is a mess to work with:
- names come as multilingual objects (
{"deu": [...], "eng": [...]}), and values, winners and bid counts come as parallel arrays per lot that often don't line up; - framework agreements report ceilings, not real spend. Mixed in with real awards, they ruin any average;
- estimated values sit in two different fields (lot level or procedure level), and currencies are separate from the amounts;
- there's no "discount" and no "how competitive was it" field, so you have to compute them yourself.
This Actor turns that into one flat row per awarded lot:
- buyer, winner, awarded value, estimated value, discount % (estimate vs award), number of bids, CPV, country, publication date and award date;
- framework agreements detected and excluded by default, so they don't get mixed into real spend;
- a completeness flag (
complete/partial/minimal) on every row, so you know what to trust; - outliers flagged rather than dropped: discount above 60 % in absolute value, or more than 50 bids. You decide what to do with them;
retrieved_at(UTC) and the TED URL on every row, so each figure can be checked against the source.
Competing TED Actors return raw notices. This one returns award records you can analyse.
Who is it for?
Bid managers who want to benchmark competitors and typical discounts, sales teams in construction (CPV 45) or IT (CPV 72) looking for buyers, journalists and researchers studying competition in public procurement, and data teams who need a clean feed without writing a TED parser.
Input
| Field | Default | Notes |
|---|---|---|
countries | IT, ES, DE | ISO-2 or ISO-3 code of the buyer's country (any EU/EEA country works) |
cpvPrefixes | 45, 72 | CPV prefix, 2–8 digits (45 = construction works, 72 = IT services) |
lastNDays | 7 | Publication window ending today |
dateFrom / dateTo | – | Explicit publication date range (YYYY-MM-DD); overrides lastNDays |
minValue | – | Minimum awarded value in EUR |
excludeFrameworkAgreements | true | Framework values are ceilings, not spend |
onlyCompleteRows | false | Keep only rows with winner + EUR value + number of bids |
maxNotices | – | Optional safety cap |
{ "countries": ["IT", "DE"], "cpvPrefixes": ["45"], "lastNDays": 14, "minValue": 500000 }
Output
Real rows from TED, as returned by this Actor.
Hannover, notice 726403-2026 (complete row, no estimate published):
{"notice_id": "726403-2026","url": "https://ted.europa.eu/en/notice/-/detail/726403-2026","row": 1, "rows_in_notice": 1,"country": "DEU", "cpv_division": ["45"],"buyer": "Landeshauptstadt Hannover - Fachbereich Gebäudemanagement","winner": "H.O. Schlüter GmbH","awarded_value": 1114530.38, "awarded_currency": "EUR", "awarded_value_eur": 1114530.38,"estimated_value": null, "estimated_currency": null, "estimated_value_eur": null,"discount_pct": null,"tenders_received": 3,"publication_date": "2026-10-20", "award_date": "2026-10-01","framework_agreement": false, "lot_alignment": "direct","completeness": "complete", "is_complete": true,"outlier": false, "outlier_flags": [],"retrieved_at": "2026-10-20T11:50:11+00:00","source": "Source: TED, European Union; modified from the original","licence": "Commission Decision 2011/833/EU"}
A row with a discount (ASST Brianza → RADAR SRL, notice 579172-2026): awarded €12,042,549.91 against an estimate of €13,684,138.55, so discount 12.0 %, from 7 bids.
Field notes:
discount_pct= (estimated − awarded) / estimated × 100. It is computed only when both values are in EUR and the row is not a framework agreement. A negative value means the award came in above the estimate.completeness:complete= winner + EUR awarded value + number of bids, and not a framework agreement;partial= winner or value present;minimal= neither.lot_alignment:ambiguouswhen TED's per-lot arrays don't match one-to-one. Values we couldn't assign safely are leftnullinstead of being guessed.outlier_flags:discount_abs_gt_60pct,bids_gt_50.
The dataset has three views: Overview, Competition & discount, Provenance.
Coverage limits (please read)
The Actor can only clean what buyers actually publish:
- Estimated value (needed for the discount) is present in about 90–95 % of Italian awards, 27–40 % of Spanish awards and only 8–10 % of German awards. So discount analysis is solid for Italy and thin for Germany.
- The number of bids and the winner are sometimes missing. Use
completenessoronlyCompleteRows. - Only standard contract-award notices (
can-standard, eForms) published on TED are covered. Below-threshold national tenders are not on TED. - Values in currencies other than EUR are kept in
awarded_value/awarded_currencybut are not converted, so the*_eurfields stay null for them. - Outliers are often data-entry errors by the buyer (for example a discount close to 100 %). They are flagged rather than corrected.
Licence and attribution
Data comes from the TED API v3 (anonymous access), published by the Publications Office of the European Union and reused under Commission Decision 2011/833/EU, which allows commercial reuse with attribution. Rows are restructured and enriched (discount, flags), so: "Source: TED, European Union; modified from the original." Every row carries this attribution in source. If you republish the data, keep it. This Actor is not affiliated with or endorsed by the European Union.
Pricing
Pay per result: you pay only for the award rows delivered (see the Pricing tab).
FAQ
How fresh is the data? It is fetched live from TED on every run. retrieved_at tells you exactly when.
Can I schedule it? Yes. A daily Apify schedule with lastNDays: 2 gives you a rolling feed.
Why did a row disappear when I set minValue? Rows without an awarded value in EUR can't pass a EUR threshold.