German & EU Tenders: Public Procurement Monitor avatar

German & EU Tenders: Public Procurement Monitor

Pricing

from $10.00 / 1,000 scored match returneds

Go to Apify Store
German & EU Tenders: Public Procurement Monitor

German & EU Tenders: Public Procurement Monitor

German and EU public tenders in one deduplicated list: public procurement notices for Germany from oeffentlichevergabe.de (öffentliche Ausschreibungen, Vergabe) and TED, other EU countries via TED. Tenders scored to your CPV codes, keywords and regions, with deadlines. Daily tender alerts.

Pricing

from $10.00 / 1,000 scored match returneds

Rating

0.0

(0)

Developer

Lindenwerk Data

Lindenwerk Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 hours ago

Last modified

Share

What is German & EU Tenders Monitor?

Find public tenders in Germany (öffentliche Ausschreibungen) that actually fit your business. This Actor combines the official German notice service oeffentlichevergabe.de (federal, state and municipal notices, including many below EU thresholds) with the EU's TED (Tenders Electronic Daily). It removes cross-posted duplicates and scores every notice against your profile (CPV codes, German/English keywords, regions, contract type and value). You get one clean, flat row per opportunity, with the submission deadline, a relevanceScore from 0 to 100 and plain-language matchReasons.

Use it as a daily tender alert (monitor mode returns only notices you haven't seen yet), for a one-off market scan of the last 31 days (backfill), or for competitor tracking (award notices with winners and awarded values).

Who it's for

  • Bid managers and sales teams at companies that sell to the public sector: one scored shortlist each morning instead of checking several portals.
  • SMEs and Mittelstand suppliers (IT, construction, facility services, consulting, supplies) that want to find below-threshold German tenders (Unterschwellenvergaben) that TED-only tools miss.
  • Tender consultants and agencies who monitor several client profiles (one saved task and stateKey per client).
  • Analysts and AI agents that need clean, structured public procurement data (CPV, NUTS, deadlines, values, award winners) through an API.

What it does

  • Downloads the daily eForms open-data export from oeffentlichevergabe.de (CC0) and parses the eForms XML.
  • Queries the TED Search API v3 for the countries you choose (default DE; any EU/EEA country works).
  • Deduplicates across sources. A notice published on both portals becomes one row, sources: ["oeffentlichevergabe.de", "TED"], with both links. Matching uses the eForms notice UUID first (TED stores it as notice-identifier), then the TED publication number, then a conservative fuzzy match on buyer, title and deadline. Older versions of a notice are collapsed. The same applies when a buyer re-publishes an identical procedure under a new id; the older ids go to relatedNoticeIds.
  • Scores relevance with transparent rules (no LLM, no black box):
    • CPV codes by prefix: 72 matches all IT services, 4521 matches all building construction work.
    • Keywords in DE and EN, matched in title (weight 1.0) and description (0.5). Rare words count more (IDF). Umlauts and compound words are handled, so Reinigung also finds Unterhaltsreinigung.
    • Hard filters: excludeKeywords, regions (German state names or NUTS prefixes), contractTypes, minValue/maxValue, onlyOpen (submission deadline still in the future) and competitorNames (awards).
  • Three modes: monitor, backfill and awards (see below).
  • GDPR by default. Named contact persons, personal e-mail addresses and phone numbers are dropped. Only organisation names and functional contacts (e.g. vergabestelle@…, "Zentrale Vergabestelle") are kept.

Why it beats single-source tender scrapers

TED-only scrapersSingle German portal scrapersThis Actor
EU-threshold tenders (TED)✅partly✅
German below-threshold notices (UVgO/VOB/A national)❌partly✅ (via oeffentlichevergabe.de, all federal states)
Cross-source deduplication❌❌✅ one row per notice, both links kept
Relevance scoring with reasons❌❌✅ relevanceScore + matchReasons
"Only new since last run"rarelyrarely✅ persistent state
Award / competitor trackingpartly❌✅ winners + awarded values
Login, proxies, scraping of HTML pagessometimesusuallynone: official open-data APIs only

In a 30-day test window (5 Sep to 4 Oct 2026, buyer country DE) the Actor read 14,234 German eForms notice versions and 6,981 TED notices. It merged 6,915 cross-posts, collapsed 961 re-publications and returned 13,237 unique tender notices. About half of the German notices (7,217 of 14,132) were never published on TED, so a TED-only alert misses them. 66 notices appeared only on TED.

How to get daily German tender alerts

  1. Click Start with the prefilled IT-services example. It's a quick market scan (backfill) that returns up to 25 scored German and EU tenders, so you see real output before you change anything.
  2. Replace the CPV codes and keywords with your own. Optionally add regions (NUTS codes or German states), contract types and a value range.
  3. Pick a mode: backfill for a market scan of the last days, monitor for daily alerts that return only notices you haven't seen yet, or awards for competitor tracking.
  4. Look at the results in the Output tab (views "Matches" and "Awards") or download them as JSON, CSV or Excel.
  5. For daily alerts, switch mode to monitor, save the input as a task and add a schedule (for example every weekday at 07:00).
  6. Send new matches on with Apify integrations (Slack, Google Drive, Make, Zapier, n8n or a webhook), or call the Actor from your own code through the Apify API.

Modes

modeWhat you getTypical use
monitor (default)Notices published in the last lookbackDays (default 1) that previous runs with the same stateKey have not returned. A first run that finds nothing looks back 7 days once (see below).Schedule daily (e.g. 07:00 Europe/Berlin) and connect to e-mail, Slack, a CRM or a spreadsheet.
backfillEverything between dateFrom and dateTo (max 31 days; without dates: the last 7 days). Does not touch the monitor state.Market scan, pipeline building, testing a profile.
awardsContract award notices only, with winnerNames, awardedValue and numberOfTenders. Uses dateFrom/dateTo or lookbackDays.Competitor and price intelligence.

Note: oeffentlichevergabe.de publishes a full day's export the following morning, so German notices arrive with about one day of delay. TED publishes on working days (nothing at weekends) and is queried up to today.

The Console form vs. API defaults

  • The Console form opens with a short trial: mode = backfill (the last 7 days), the IT profile (CPV 72/48 and five keywords) and maxResults = 25. One click shows the 25 best current matches for at most USD 0.25. This prefill is also what Apify's daily automated Store test runs. It keeps no state, so it returns rows on any day, weekends and holidays included.

  • Before you schedule it, switch mode to monitor and raise maxResults, or set it to 0 for no limit.

  • API calls, tasks and schedules that leave a field out get the defaults: mode = monitor, lookbackDays = 1, maxResults = 500. The prefill values only fill the form.

  • Warning for one-off API and AI-agent calls: leaving out mode runs monitor mode. That returns only notices from the last lookbackDays (default 1) that no earlier run with the same stateKey has returned, and it remembers them, so the same call repeated returns nothing new. For a one-off search, set "mode": "backfill" (without dateFrom/dateTo it covers the last 7 days and keeps no state):

    {
    "mode": "backfill",
    "cpvCodes": ["72", "48"],
    "keywords": ["IT-Sicherheit", "Informationssicherheit", "IT security"],
    "regions": ["Bayern", "Berlin"],
    "maxDaysUntilDeadline": 21,
    "maxResults": 50
    }
  • First monitor run on a quiet day: a monitor run with no saved state (the first run for a stateKey, or one with resetState) that finds nothing new in its lookback window looks back firstRunBackfillDays (default 7) once. That way a monitor started on a Sunday or a public holiday still shows the open tenders. Everything it returns is remembered, so the next run is a normal monitor run. Set firstRunBackfillDays to 0 to turn this off.

  • Quiet days and outages: a monitor run with nothing new still ends Succeeded, with 0 rows and a status message ("no new matching notices since the last run"). Nothing is charged. If one source is down or runs out of time (a failed export day, a TED error), the run keeps everything that source did deliver (finished export days, TED pages fetched so far) and continues with the other source. It never hides this: the status message starts with PARTIAL DATA, the log has a PARTIAL SOURCE line with the missing days, and RUN_SUMMARY lists sourceStatus, partialSources, missingDays and warnings. You only pay for rows that are delivered. If every source is unreachable, the run ends Failed with a clear message. Nothing is charged and the monitor state is left unchanged, so the next run picks those days up again. A source that hangs is given up after 210 s in short monitor runs; backfills get 60 s plus 25 s per day of the window (about 14 minutes for 31 days), always leaving time before the run timeout, so a run never gets stuck.

Input examples

1. IT services (Germany-wide, open tenders only)

{
"mode": "monitor",
"lookbackDays": 1,
"countries": ["DE"],
"profileName": "it-services",
"cpvCodes": ["72", "48"],
"keywords": ["Software", "IT-Dienstleistung", "IT-Beratung", "Cloud", "Rechenzentrum", "Datenbank",
"IT-Sicherheit", "Webanwendung", "software development", "IT services"],
"excludeKeywords": ["Druckerpapier"],
"onlyOpen": true,
"minScore": 40
}

2. Construction works in Bavaria and Baden-Württemberg, at least EUR 100k

{
"mode": "backfill",
"dateFrom": "2026-09-05",
"dateTo": "2026-10-04",
"profileName": "construction-south",
"cpvCodes": ["45"],
"keywords": ["Hochbau", "Rohbau", "Sanierung", "Neubau", "Dacharbeiten", "Fassade", "Trockenbau",
"Schule", "Kindertagesstätte", "Erweiterungsbau"],
"excludeKeywords": ["Objektplanung", "Planungsleistungen", "Projektsteuerung"],
"contractTypes": ["works"],
"regions": ["Bayern", "Baden-Württemberg"],
"minValue": 100000,
"minScore": 60
}

(minValue only removes notices whose estimated value is known and lower. Many notices publish no value and are kept.)

3. Facility management in Berlin and Brandenburg

{
"mode": "monitor",
"lookbackDays": 1,
"profileName": "facility-berlin-brandenburg",
"cpvCodes": ["909", "7971", "79993", "9834113", "7731", "507"],
"keywords": ["Gebäudereinigung", "Unterhaltsreinigung", "Glasreinigung", "Hausmeister", "Facility Management",
"Wachschutz", "Sicherheitsdienst", "Winterdienst", "Grünpflege", "Gebäudemanagement"],
"excludeKeywords": ["Abwasser", "Kanalreinigung"],
"contractTypes": ["services"],
"regions": ["Berlin", "Brandenburg"],
"minScore": 40
}

4. Competitor tracking (awards)

{
"mode": "awards",
"dateFrom": "2026-09-05",
"dateTo": "2026-10-04",
"cpvCodes": ["72", "48"],
"competitorNames": ["Example IT GmbH"],
"minScore": 40
}

More ready-to-run inputs are in the examples/ folder of the source code.

Input reference (short)

FieldMeaning
cpvCodesCPV prefixes (digits only, 2–8 digits, check digit optional). 72 = IT services, 45 = construction work, 909 = cleaning, 4873 / 72212730 = security software, 7971 = guarding / security services (not IT).
keywords / excludeKeywordsGerman or English terms. Put a term in "quotes" for whole-word matching. Terms of 3 characters or fewer always match whole words only.
regionsGerman state names (Bayern, Bavaria, NRW, …) or NUTS prefixes (DE21, DE300, AT13). Matches buyer address or place of performance.
contractTypesworks, services, supplies.
minScore0–100. Only notices at or above it are returned (and charged). 40 is a good default; 60 is strict. Keywords raise the score, so a high minScore with only a few keywords can return nothing (a CPV-only match scores 50).
onlyOpenDrop tenders whose submission deadline has passed (default true).
minDaysUntilDeadline / maxDaysUntilDeadlineOptional deadline window in days from the run date (the daysUntilDeadline field: submission deadline, or the participation deadline if no submission deadline is published). "maxDaysUntilDeadline": 21 = due within 3 weeks; "minDaysUntilDeadline": 5 skips tenders you can't prepare in time. Not set = no filter. When either is set, notices without a published deadline are excluded. Filtered notices are never charged.
countriesISO-2 country codes for TED (DE, AT, FR, …). oeffentlichevergabe.de is always Germany.
sourcesoeffentlichevergabe, ted (default both).
maxResultsHard cap on rows (and therefore on cost) per run, best matches first. Default 500 (the Console form prefills 25).
sortByrelevance, deadline or publicationDate.
stateKeySeparate monitor memory per profile (e.g. one per customer). resetState: true starts fresh.
firstRunBackfillDaysMonitor only: how far a first run with no saved state looks back if its normal window is empty. Default 7, 0 = off.

Without cpvCodes, keywords or competitorNames, the Actor returns an unscored feed (all notices after filters), which is charged at the lower notice price.

Sample output

One row (abridged; the full sample is in sample-output.json):

{
"noticeId": "552260a3-3c12-465d-8fad-f46e5319acca",
"noticeType": "tender",
"title": "Datenschutzmanagementsystem",
"buyerName": "ekom21 - Kommunales Gebietsrechenzentrum Hessen",
"buyerCity": "Gießen",
"buyerState": "Hessen",
"buyerNuts": "DE731",
"buyerEmail": "vergabestelle@ekom21.de",
"buyerContactPoint": "Vergabestelle",
"cpvMain": "72268000",
"contractNature": "services",
"procedureType": "open",
"aboveEuThreshold": true,
"submissionDeadline": "2026-10-06T10:00:00+02:00",
"daysUntilDeadline": 2,
"isOpen": true,
"publicationDate": "2026-10-01",
"documentsUrl": "https://www.had.de/NetServer/TenderingProcedureDetails?function=_Details&TenderOID=…",
"oeffentlichevergabeUrl": "https://oeffentlichevergabe.de/ui/de/search/details?noticeId=552260a3-3c12-465d-8fad-f46e5319acca",
"tedUrl": "https://ted.europa.eu/en/notice/-/detail/676777-2026",
"tedPublicationNumber": "676777-2026",
"sources": ["oeffentlichevergabe.de", "TED"],
"dedupMethod": "notice-id",
"relevanceScore": 80,
"matchReasons": [
"Main CPV 72268000 matches profile CPV 72",
"Keyword 'Cloud' in description",
"Keyword 'Rechenzentrum' in description",
"Deadline in 2 day(s)"
],
"profileName": "it-services"
}

Award rows additionally carry winnerNames, awardedValue, awardedCurrency and numberOfTenders. Every run also stores a RUN_SUMMARY record in the key-value store: notices per source, whether each source is complete (sourceStatus, missingDays), dedup statistics, filter counts and matches.

Output fields

GroupFields
IdentitynoticeId, noticeVersion, noticeType (tender, award, planning, modification, change, other), formType, noticeSubtype, relatedNoticeIds
Contenttitle, description (shortened, see descriptionMaxLength), cpvMain, cpvCodes, contractNature, procedureType, legalBasis, aboveEuThreshold, lotCount
BuyerbuyerName, buyerCity, buyerPostalCode, buyerState, buyerNuts, buyerCountry, buyerWebsite, buyerEmail and buyerContactPoint (functional only), placeOfPerformanceNuts
Money and datesestimatedValue, currency, publicationDate, submissionDeadline, participationDeadline, daysUntilDeadline, isOpen
LinksoeffentlichevergabeUrl, tedUrl, tedPublicationNumber, noticeUrl, documentsUrl, submissionUrl
MatchingrelevanceScore, matchReasons, profileName, sources, dedupMethod, language, retrievedAt
AwardswinnerNames, awardedValue, awardedCurrency, numberOfTenders (awardedValue is only filled on award and contract-modification notices; it is always null on open tenders, where estimatedValue holds the estimate)

Export as JSON, CSV, Excel or XML from the dataset, or read it through the API.

Pricing (pay per event)

EventPrice
Actor startUSD 0.00005
scored-match: a notice that matched your profile at or above minScoreUSD 0.01
notice: a row in an unscored feed (no CPV, keyword or competitor profile)USD 0.003

Notices below minScore, filtered notices and duplicates are never charged. Platform compute is included in these prices. You can cap cost with maxResults and with the run's maximum total charge. The Actor stops cleanly when that limit is reached.

Worked examples per run (real runs on 4 Oct 2026, buyer country DE, 30-day window 5 Sep to 4 Oct 2026; the example inputs are in examples/):

RunRows returnedYour cost
Daily monitor, IT services profile (one day's notices)1313 × 0.01 = USD 0.13
30-day backfill, IT services, open tenders, minScore 40496USD 4.96
30-day backfill, construction, Bavaria + BW, ≥ EUR 100k, minScore 60442USD 4.42
30-day backfill, facility management, Berlin + Brandenburg48USD 0.48
30-day awards, IT award notices (competitor tracking)411USD 4.11
30-day unscored feed, capped with maxResults: 10001,0001,000 × 0.003 = USD 3.00

Each run also triggers the Actor start event (USD 0.00005).

Monthly estimate for a daily monitor schedule (same volumes; a daily monitor sees tenders while they are still open, so it returns slightly more than a backfill run at the end of the month):

ProfileMatches per monthCost per month
IT services, Germany-wide, minScore 40~500–650≈ USD 5–6.50
Construction works, Bavaria + BW, ≥ EUR 100k, minScore 60~450–500≈ USD 4.50–5
Facility management, Berlin + Brandenburg~50–60≈ USD 0.50–0.60
Unscored full feed, all German tenders~13,200≈ USD 40 (or set maxResults)

For comparison, commercial German tender-alert subscriptions typically cost a monthly fee per user. Here you pay only for notices that actually matched.

Use with AI agents (MCP)

The input schema is written so that an LLM can call the Actor unambiguously: enums, defaults, examples and descriptions in plain English. Add the Actor to the Apify MCP server in Claude Desktop, Cursor, VS Code or any other MCP client:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=actors,lindenwerk/german-eu-tender-matcher"
}
}
}

Then ask, for example: "Find open IT security tenders in Bavaria and Berlin from the last 7 days with a deadline in the next 3 weeks, and summarise the top 5 with their deadlines." The agent maps this to mode: backfill, cpvCodes: ["72"], keywords: ["IT-Sicherheit", "Informationssicherheit", "IT security"], regions: ["Bayern", "Berlin"] and maxDaysUntilDeadline: 21. It can then use matchReasons to explain why each result fits. Agents should always set mode explicitly: without it the call runs as a monitor (see above).

You can also call it via the Apify API (POST https://api.apify.com/v2/acts/lindenwerk~german-eu-tender-matcher/run-sync-get-dataset-items) or the Python/JS clients, and connect it to Make, Zapier, n8n, Google Sheets or Slack through Apify integrations.

Data sources and licences

The Actor processes public, non-personal procurement data that contracting authorities are legally required to publish. It uses official open-data interfaces only: no login, no proxies, no HTML scraping.

  • oeffentlichevergabe.de, the German national notice service (Bekanntmachungsservice) run on behalf of the Federal Ministry for Economic Affairs: open-data eForms export (/api/notice-exports), published under CC0 1.0 (see the portal's publication policy at https://oeffentlichevergabe.de/ui/de/publicationPolicy).
  • TED (Tenders Electronic Daily), Publications Office of the European Union: Search API v3 (https://api.ted.europa.eu/v3/notices/search). © European Union. Reuse is authorised under Commission Decision 2011/833/EU on the reuse of Commission documents. Source: TED, https://ted.europa.eu.
  • The Actor only reshapes and scores the official data. Always check the original notice (links included) and the tender documents before you bid. Deadlines in the official notice prevail.

GDPR and responsible use

Public procurement notices sometimes contain the names, e-mail addresses or phone numbers of individual employees. This Actor drops them by default: it never outputs phone numbers, removes person-like e-mail addresses (e.g. firstname.lastname@) and keeps only functional contact points such as "Vergabestelle" or vergabe@…. The same applies to free text: phone and fax numbers, personal e-mail addresses and "Frau/Herr

FAQ

How is relevanceScore calculated? CPV evidence (main CPV match 0.5, additional CPV 0.35) and keyword evidence (title hits count double, rare terms weigh more) are combined as 100 × (1 − (1 − cpv) × (1 − keywords)). In a profile with both CPV codes and keywords, a CPV-only match scores 50, a single title keyword about 46, and CPV plus a title keyword about 70–80. Several strong keyword hits approach 100. If your profile has only CPV codes, a main-CPV match scores 100 and an additional-CPV match 70. If it has only keywords, the keyword evidence alone sets the score. matchReasons lists every contribution.

Why do some rows have no estimated value? Many buyers don't publish one. Value filters keep notices with unknown values so you don't miss them.

Which deadline is submissionDeadline? The tender submission deadline (eForms TenderSubmissionDeadlinePeriod, earliest across lots). For two-stage procedures, participationDeadline holds the request-to-participate deadline. Times are Europe/Berlin unless the notice states otherwise. If no time is given, 23:59:59 is assumed.

Can I monitor several profiles? Yes. Create one saved task per profile, each with its own stateKey.

How fresh is the data? TED is queried up to the current day. oeffentlichevergabe.de publishes each day's export the next morning, so German-only notices arrive about one day after publication. Schedule the monitor for the morning (e.g. 07:00 Europe/Berlin).

Does it cover other countries? TED covers all EU/EEA countries: set countries, e.g. ["DE", "AT"]. The German below-threshold notices come from oeffentlichevergabe.de and are Germany only.

Can I only get tenders due soon (or not too soon)? Yes. maxDaysUntilDeadline keeps notices whose deadline is at most that many days after the run, minDaysUntilDeadline at least that many. Both count from the run date to the deadline in daysUntilDeadline. With either set, notices without a published deadline are dropped. Dropped notices are not charged.

What does a run with no matches cost? Only the Actor start event (USD 0.00005). You never pay for notices that were filtered out, below minScore, duplicates or already returned by an earlier monitor run.

Is this an official service? No. It is an independent tool built on the official open data. Always check the original notice and the tender documents before you bid; the official notice prevails.

Is it legal to use this data? Yes. Procurement notices are published so that companies can bid. oeffentlichevergabe.de data is CC0 and TED data may be reused under Commission Decision 2011/833/EU with source attribution. Personal contact data is removed (see GDPR above).

Examples

Other Lindenwerk Data Actors


Deutsch (Kurzfassung)

Öffentliche Ausschreibungen aus oeffentlichevergabe.de und TED in einer Liste: dedupliziert und nach Ihrem Profil bewertet. Der Actor lädt die offiziellen Open-Data-Bekanntmachungen (eForms, CC0) des Bekanntmachungsservice des Bundes (auch Unterschwellenvergaben nach UVgO/VOB/A) sowie EU-weite Ausschreibungen aus TED. Doppelte Veröffentlichungen werden zusammengeführt, und jede Bekanntmachung wird nach CPV-Codes, Suchbegriffen (DE/EN), Bundesländern/NUTS, Auftragsart und Auftragswert bewertet (relevanceScore 0–100 mit Begründung in matchReasons).

  • monitor (Standard bei API-Aufrufen und Zeitplänen): täglich nur neue Ausschreibungen (ideal als Ausschreibungs-Alert per Zeitplan)
  • backfill: Marktüberblick über bis zu 31 Tage. Das Formular in der Console startet damit: die letzten 7 Tage, höchstens 25 Treffer. Vor dem Einplanen auf monitor umstellen. Achtung: Ein API-Aufruf ohne mode läuft als monitor; für eine einmalige Suche "mode": "backfill" setzen.
  • awards: Zuschlagsbekanntmachungen mit Gewinnern und Auftragswerten (Wettbewerbsbeobachtung)

Optional: minDaysUntilDeadline / maxDaysUntilDeadline (Tage bis zur Angebotsfrist, z. B. 21 = Frist in den nächsten 3 Wochen); Bekanntmachungen ohne Frist fallen dann heraus und werden nicht berechnet.

Abrechnung pro Treffer (USD 0,01 je bewertetem Treffer, USD 0,003 je ungefilterter Bekanntmachung). Personenbezogene Kontaktdaten (Namen, persönliche E-Mail-Adressen, Telefonnummern) werden standardmäßig entfernt. Quellen: oeffentlichevergabe.de (CC0) und TED, © Europäische Union (Weiterverwendung gemäß Beschluss 2011/833/EU).

Made by Lindenwerk Data.