Every public tender above the EU thresholds is published on TED (Tenders Electronic Daily), and TED has an official, free search API. Paid alert services charge hundreds of euros a year for what is essentially a saved query. Here's the DIY version.
The query
TED's search API (https://docs.ted.europa.eu/api/latest/search.html) takes an "expert query", e.g. IT services (CPV 72000000) from German or Austrian buyers published today:
import requests, datetime q = "classification-cpv IN (72000000) AND buyer-country IN (DEU AUT) AND publication-date=" + datetime.date.today().strftime("%Y%m%d") r = requests.post("https://api.ted.europa.eu/v3/notices/search", json={ "query": q, "fields": ["publication-number", "notice-title", "buyer-name", "deadline-receipt-tender-date-lot"], "limit": 100}) for n in r.json()["notices"]: print(n["publication-number"], n.get("notice-title")) Turning it into alerts
- Store the publication numbers you've already sent (a small JSON file or a sheet).
- Run the script daily (cron, GitHub Actions) and send only new notices to email/Slack.
- Link each notice as
https://ted.europa.eu/en/notice/-/detail/<publication-number>.
Gotchas
- Field names are multilingual objects; pick your language and fall back to the original.
- Values and winners live in different fields for contract notices vs award notices.
- Paging: use the
iterationNextToken/page parameters, and keep queries narrow.
TED data is EU open data and can be reused, including commercially, with attribution.
Disclosure: I maintain a hosted version, TED Tenders Scraper on Apify, that flattens all of this into one row per notice with an "only new" alert mode ($2.50 per 1,000 notices). The snippet above is enough for a single saved search. If you'd rather get a ready Excel every Monday with all open IT tenders across Europe (English titles included), I also publish EU IT Tenders & Grants Weekly.


