EU Tender Monitor - TED Alerts avatar

EU Tender Monitor - TED Alerts

Pricing

from $1.60 / 1,000 baseline tenders

Go to Apify Store
EU Tender Monitor - TED Alerts

EU Tender Monitor - TED Alerts

Get alerted the moment a new EU public tender matching your business is published on TED. Filter by CPV codes, keywords in any EU language, countries and NUTS regions; alerts only on never-seen tenders via the official TED API. Clean output, no buyer contact persons.

Pricing

from $1.60 / 1,000 baseline tenders

Rating

0.0

(0)

Developer

Lowland Data

Lowland Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

2 days ago

Last modified

Share

EU Tender Monitor — TED Alerts

Watches TED (Tenders Electronic Daily, the EU's official procurement journal — every above-threshold public tender in the Union) for notices matching your buyer profile: CPV codes, keywords in any EU language, countries, NUTS regions, value floor. It alerts the moment a matching tender is published, and it remembers what it has already told you — so an alert always means something changed, never a re-scrape of yesterday's list.

It reads the official TED Search API — the access route the EU itself provides for reuse — and the output is GDPR-clean by construction: buyer organizations, CPV codes, deadlines and values, but no contact persons, no emails, no phone numbers. Safe to store, share with your bid team, or import into a CRM.

Quick start (30 seconds, no account or API keys needed)

  1. Run the actor with the prefilled input (IT-services tenders, EU-wide, last 3 days) — it finishes in a few seconds and shows a baseline.
  2. Replace the demo profile with your own: your CPV codes, your keywords, your countries or NUTS regions.
  3. Add a daily schedule (Actor page → Schedule). From then on, runs are quiet until a tender you care about is actually published.

Who uses this

  • A software agency in Antwerp monitors cpvCodes: ["72000000"], countries: ["BE", "NL"] on a daily schedule. When a hospital publishes a systems-integration tender, the alert lands with the deadline and the ted.europa.eu link the same day — not when a sales rep stumbles on it in week three of a five-week window.
  • A bid manager at a construction group watches nutsCodes: ["BE2"] (Flanders) plus cpvCodes: ["45000000"] with minValueEur: 1000000 — only the region she can actually serve, only projects worth mobilizing for.
  • A consultancy tracking its competitors monitors noticeTypes: ["award"] on its CPV family: winnerNames and totalValueEur show who wins what, at what price, across every EU member state.
  • A market-entry analyst runs keywords: ["laboratorium", "laboratory"] EU-wide for a quarter of demand data — TED translates every title into all 24 EU languages, so keywords match tenders from Portugal to Finland.
  • A grants-and-tenders desk pairs this with its US sibling (US RFP Monitor) for one transatlantic pipeline with identical alert semantics.

What you get

One JSON item per event: a baseline snapshot per tender on the first run, then only transitions — new matching tenders, and (opt-in) corrigenda or change notices to tenders you have already seen. A new-tender alert looks like:

{
"publicationNumber": "495369-2026",
"title": "Poland – Software package and information systems – Dostawa i wdrożenie systemu informatycznego",
"buyerName": "Szpital Wojewódzki w Katowicach",
"buyerCountry": "POL",
"cpvCodes": ["48000000", "72263000"],
"nutsCodes": ["PL22A"],
"noticeCategory": "contract-notice",
"sourceNoticeType": "cn-standard",
"description": "Przedmiotem zamówienia jest dostawa i wdrożenie systemu informatycznego wraz z usługami utrzymania.",
"sourceLanguage": "pol",
"publicationDate": "2026-07-17",
"deadline": "2026-08-20",
"estimatedValueEur": 1030063,
"url": "https://ted.europa.eu/en/notice/-/detail/495369-2026",
"isBaseline": false,
"isUpdate": false
}

Field honesty notes:

  • title is TED's official translation (all 24 EU languages exist; you get English). Its pattern is "Country – CPV label – buyer's own words", and the buyer's own words stay in the source language.
  • description is source-language only — TED does not translate descriptions. sourceLanguage tells you which.
  • estimatedValueEur / totalValueEur appear only when the buyer published a value — most notices carry none, and absence does not mean small.
  • deadline is the earliest lot deadline on the notice; always verify on the linked notice before planning a bid.
  • Award notices carry winnerNames and winnerCountries — organization names as the EU officially publishes them, no contact data.

How much does EU tender monitoring cost?

Pay per outcome — checking costs nothing; you pay when the monitor tells you something new:

  • New matching tender (the alert): $0.02 — also for change alerts.
  • Baseline item (first run only): $0.002.
  • Actor start: $0.005. Everything included - there are no separate platform-usage charges, and higher Apify plans get automatic unit-price discounts.

Cost feel: a focused profile (one CPV family, two countries) sees a handful of new tenders per working day → roughly $2–8/month for complete coverage of your niche, with the one-time baseline (say 100 items) costing about $0.20. A run with zero new matches costs $0.005 all-in. Dedicated EU tender-alert services charge €30–200/month for the same coverage.

Why an alert costs more than a scraped row

The store's headline ("from $2.00 / 1,000 baseline results") is what a trial costs: a 100-item baseline ≈ $0.20. Apify displays every event per 1,000, so in the pricing table the alert event reads "$20.00 / 1,000" next to raw scrapers at $1–3 per 1,000 rows — but that comparison is between different things:

  • A raw TED scraper sells rows: to monitor with rows you re-download your whole query every day (~3,500 EU notices/working day) and diff them yourself.
  • This monitor sells the transition: it remembers state in your account and charges $0.02 exactly when a tender you have not seen matches your profile. Nobody buys 1,000 alerts a month.

Not technical? Let your AI assistant set it up

Paste this prompt together with a description of what you sell and where:

Set up the Apify actor lowlanddata/eu-tender-monitor to watch EU public tenders
for me. Build the input JSON from my business description:
- cpvCodes: the EU CPV classification codes for my products/services (8 digits,
e.g. 72000000 for IT services; a prefix like "72" also works)
- keywords: 3-8 words in any EU language a tender title would contain (they match
TED's official titles in all 24 languages)
- countries: ISO codes of countries I can serve (e.g. ["BE", "NL"]), or
nutsCodes for regions (e.g. ["BE2"] for Flanders)
- noticeTypes: ["contract-notice"] to bid, add "award" to track winners
- minValueEur only if I gave a minimum deal size
Leave alertOn, emitBaseline and maxItems at their defaults. Run it once and show
me the baseline as a table (title, buyer, country, deadline, value, url). Then
create a daily schedule for it and set up a notification so I get an email when
a run produces items.

Coverage — measured, not promised

  • Source: the official TED Search API, keyless. TED carries every above-EU-threshold tender from all member states plus EEA and enlargement countries — ~3,500–4,100 notices per working day (measured July 2026), zero on weekends (the OJ S publishes working days only).
  • Below-threshold national tenders are out of scope by design — they live on national portals (BOAMP, TenderNed, PLACSP, …), not TED. This actor is the EU layer; it does not pretend otherwise.
  • Keyword matching: titles in all 24 EU languages (server-side, official TED index). Descriptions only in their source language, and only with alsoMatchDescriptions: true. CPV codes are the reliable, language-free filter — prefer them.
  • A profile broader than ~10,000 notices per run is truncated honestly (the run status says so and suggests narrowing) — precision over silent gaps.

How the monitor thinks

  • First run = baseline. It fetches your profile's matches from the last lookbackDays (default 7), pushes them flagged isBaseline: true at the low baseline price, and memorizes them. emitBaseline: false seeds silently instead.
  • After that, only transitions. Each run queries from the previous run (one day of overlap; the memory absorbs duplicates) and pushes only tenders it has never alerted. Corrigenda and change notices to seen tenders alert as isUpdate: true when alertOn: "new-and-updated"; with alertOn: "new" they stay silent but are remembered, so switching later never replays history.
  • Editing the profile starts a fresh baseline — matching-relevant inputs are the profile's identity, so a changed profile can never flood you with alerts computed against another profile's memory. maxItems, emitBaseline and schedule changes do not restart anything.
  • Memory lives in a named key-value store (stateStoreName, default ted-monitor-state) in your account. Run several profiles on separate schedules against the same store — they never interfere. resetState: true wipes the current profile's memory.
  • Re-running after a crash or overlap re-alerts at most the last few unsaved items — state is checkpointed during the run.

Input reference

FieldTypeDefaultNotes
keywordsarray[]Any EU language; matched against official titles in all 24 languages. OR within the list.
cpvCodesarray["72000000"]*Hierarchical: 72000000 or the prefix 72 match all IT-services codes.
countriesarray[]Buyer country, 2- or 3-letter ISO (BE or BEL).
nutsCodesarray[]Place of performance, prefix match (BE2 = Flanders).
noticeTypesarray["contract-notice"]Also: prior-information, award.
alsoMatchDescriptionsbooleanfalseDescriptions are source-language only — see coverage notes.
minValueEurintegerTenders without a published value always pass.
lookbackDaysinteger7Baseline reach on the first run (max 30).
alertOnstring"new""new-and-updated" adds corrigendum/change alerts.
emitBaselinebooleantruefalse = silent seeding.
resetStatebooleanfalseOne-shot: wipe this profile's memory.
maxItemsinteger500Overflow alerts on the next run, never lost.
stateStoreNamestring"ted-monitor-state"Only change to fully isolate monitor instances.

* At least one of keywords, cpvCodes, countries, nutsCodes is required — an unfiltered profile would be all of TED.

Scheduling and API use

Run it daily (TED publishes working days only — weekend runs simply find nothing and cost $0.005). Pair the schedule with a Monitoring alert on "dataset items

0" to get an email exactly when a tender matched.

curl -X POST \
"https://api.apify.com/v2/acts/lowlanddata~eu-tender-monitor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"cpvCodes": ["72000000"], "countries": ["BE"], "lookbackDays": 7}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lowlanddata/eu-tender-monitor').call({
cpvCodes: ['72000000'],
countries: ['BE', 'NL'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items); // only new tenders since the last run
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("lowlanddata/eu-tender-monitor").call(run_input={
"cpvCodes": ["72000000"],
"countries": ["BE", "NL"],
})
items = client.dataset(run["defaultDatasetId"]).list_items().items

Typical daily runs finish in well under a minute, comfortably inside the 300s sync-call wall; a 30-day EU-wide baseline on a broad CPV family is the one case that can take a few minutes — run it async once.

Use it with AI agents (MCP)

Claude, Cursor and other MCP-capable agents can run this monitor as a tool through Apify's hosted MCP server: the agent builds the profile from a plain-language brief, runs it, and reads the alerts back — no glue code.

Claude Code:

$claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/eu-tender-monitor"

Cursor or Claude Desktop (add a custom connector / MCP server with this URL):

https://mcp.apify.com?actors=lowlanddata/eu-tender-monitor

Sign in with your Apify account when prompted — runs are billed to it. Setup details per client: Apify MCP docs, or start from this actor's own MCP page: apify.com/lowlanddata/eu-tender-monitor/api/mcp.

Prompts that work once connected:

  • "Watch EU tenders for cloud migration services in Belgium and the Netherlands and show me today's matches."
  • "What IT tenders over €500k were published in Flanders this week?"
  • "Who won public software tenders in Spain this month, and at what value?"

Yes — unambiguously. TED is the EU's official publication channel and its notices "can be freely reused, for commercial or non-commercial purposes" under the European Commission's reuse decision (2011/833/EU); this actor reads the official TED Search API that exists exactly for this. No login walls, no anti-bot bypass — if TED is unreachable, the run reports it rather than fighting it. And the output is safe by construction: no personal data is requested from the API in the first place (see the compliance section below).

Data source: Tenders Electronic Daily (TED), © European Union, ted.europa.eu — reused under Commission Decision 2011/833/EU.

Compliance: safe to store, safe to CRM-import

TED notices do contain personal data — buyer contact persons with direct emails and phone numbers, and beneficial-ownership names. This actor's guarantee is structural, not a filter: the TED API only returns fields that are explicitly requested, and the request whitelist simply never includes the person, contact, email, phone or beneficial-owner field families — the data never even crosses the wire, and an automated test proves that a response carrying such fields cannot reach the output. What remains is organization-level: buyer names, winner organization names, codes, dates, values. One honest limit: description and title contain text the buyer wrote — on rare occasions a buyer writes a person's name into free text. We cannot rewrite official notices; everything structured is guaranteed clean.

FAQ

Why did my second run return nothing? Because nothing new matched — that is the product working. The first run is the baseline; afterwards you only pay for tenders you have not seen. Check the run status line: it says how many notices were checked.

Does the output contain buyer contact persons or emails? No — by design. The API request itself never asks for those fields. You get the buying organization's name and the official notice link; contact details are on the notice page if you need them for a bid.

Which countries does this cover? All EU member states plus EEA and several enlargement/neighbourhood countries — anything published on TED. Filter with countries (buyer's country) or nutsCodes (where the work is performed).

Can I monitor several profiles? Yes — one schedule per profile, same actor, same state store. Each profile keeps its own memory; they never interfere.

Do I need to write keywords in every language? No. TED translates titles into all 24 EU languages and the search covers all of them — "software" matches a Polish notice. Descriptions are the exception (source language only), which is why CPV codes are the recommended primary filter.

What about tenders below the EU thresholds? They are published on national portals, not TED, and are out of this actor's scope by design.

What is a corrigendum alert? Buyers amend notices — deadline moves, changed lots. With alertOn: "new-and-updated" you get those as isUpdate: true items; with the default you never hear about them (but they are remembered).

Troubleshooting

  • "The profile matches all of TED (~3,500 notices/day)" — add at least one of keywords, cpvCodes, countries or nutsCodes.
  • "TED rejected the search query" — usually a malformed filter value; check CPV codes are digits and country codes are real ISO codes.
  • "Monitor state record … is not readable" — the state was written by a newer version; run once with resetState: true to start a fresh baseline.
  • "Coverage truncated by the per-run request budget" — the profile matched more than ~10,000 notices in one window; narrow it or lower lookbackDays.

Something else off? Open an issue on the actor's Issues tab — reports are read and answered.