German Tenders Monitor — bund.de, TED, DTVP & evergabe
Pricing
from $4.00 / 1,000 tender notices
German Tenders Monitor — bund.de, TED, DTVP & evergabe
Collect current German public-procurement notices (Ausschreibungen) from TED and service.bund.de (+ DTVP/evergabe best-effort) in one unified schema. Filter by keywords, CPV, region and deadline, dedupe across runs. Pay per notice.
Pricing
from $4.00 / 1,000 tender notices
Rating
0.0
(0)
Developer
Nerdrx
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
German Tenders Monitor — bund.de, TED, DTVP, evergabe
What is German Tenders Monitor?
German Tenders Monitor is an unofficial Apify Actor that collects current public procurement notices (Ausschreibungen) for Germany from four different portals and returns them in one unified schema.
Public tendering in Germany is deliberately fragmented: the EU publishes above-threshold notices on TED, the federal government publishes on service.bund.de, and thousands of contracting authorities publish on commercial e-procurement platforms such as DTVP and evergabe. Anyone tracking opportunities has to watch all of them, in different formats, with different field names and different date conventions.
This Actor does that watching for you. It queries each portal, normalises every notice to the same 18 fields, filters by your keywords / CPV codes / region / deadline, and remembers what it already returned so that repeated (e.g. daily) runs only produce new notices.
It is built for:
- Sales and bid teams who want a daily feed of relevant tenders in their niche.
- Procurement consultants tracking a client's market or a competitor's buyers.
- AI agents and pipelines that need clean, typed JSON rather than four HTML portals.
Unofficial. This Actor is not affiliated with, endorsed by or operated by the European Union, the German federal government, cosinex GmbH (DTVP) or Healy Hudson / evergabe. It reads publicly accessible pages and APIs. Always confirm details on the original notice before acting on them — the
noticeUrlfield links straight to it.
What can German Tenders Monitor do?
- Query four sources in one run — TED, service.bund.de, DTVP and evergabe — each
switchable on and off via the
sourcesinput. - Survive partial outages. If one portal is down, blocks the run or changes its markup, that source is logged as failed and the run continues with the others. A run never dies because one website changed.
- Filter server-side and client-side. Keywords and CPV prefixes are pushed into the TED and bund.de queries where the portal supports it, and re-applied locally to every source so the filters behave identically no matter where a notice came from. A CPV filter never discards a notice that published no CPV code — most German national notices have none.
- Understand German data. It parses
30.09.2026, 12:00 Uhrdeadlines,1.250.000,00 EURamounts,72200000-7CPV codes and NUTS codes likeDE212, and it resolves a place or a NUTS code to a Bundesland so you can filter by federal state. - Deduplicate across runs. Notice IDs seen in earlier runs are stored in the
key-value store record
SEEN, so a scheduled daily run gives you only what is new. - Only show what you can still bid on. With
onlyOpen(default on), notices whose submission deadline has passed are dropped.
What data does it extract?
Every item — regardless of source — has exactly these fields:
| Field | Type | Description |
|---|---|---|
id | string | Stable, source-prefixed identifier, e.g. ted:00512345-2026. Used for deduplication. |
source | string | ted, bund, dtvp or evergabe. |
title | string | Title of the notice (Bezeichnung der Ausschreibung). |
buyer | string | null | Contracting authority (Vergabestelle / Auftraggeber). |
description | string | null | Short description, truncated to ~500 characters. |
cpvCodes | string[] | 8-digit CPV codes, check digits stripped. Empty if the portal published none. |
procedureType | string | null | Procedure (Vergabeart), e.g. Offenes Verfahren, open. |
region | string | null | German federal state where known, otherwise the place of performance. |
country | string | Always DE — the Actor only collects German notices. |
publishedAt | string | null | Publication date, ISO 8601 UTC. |
deadlineAt | string | null | Submission deadline (Angebotsfrist), ISO 8601 UTC. null when not published. |
estimatedValue | number | null | Estimated contract value as a number, without separators. |
currency | string | null | Currency of estimatedValue, usually EUR. null when there is no value. |
noticeUrl | string | null | Direct link to the notice on the source portal. |
documentsUrl | string | null | Link to the tender documents / PDF, when the portal exposes one. |
sourceUrl | string | The URL the record was read from. |
scrapedAt | string | ISO 8601 timestamp of the run. |
Not every portal publishes every field. estimatedValue, documentsUrl and cpvCodes
are frequently missing on the German national portals; TED is the most complete source.
How to use German Tenders Monitor
- Open the Actor and click Start — the default input already returns recent German tenders from all four portals for the last 7 days.
- Narrow the feed to your market with
keywords(e.g.Software,IT-Dienstleistung) and/orcpvPrefixes(e.g.72for IT services,48for software packages,45for construction). Keywords use OR semantics and are case-insensitive. - Optionally restrict to your sales territory via
regions(e.g.Bayern,Nordrhein-Westfalen). - Set a schedule (daily at 07:00 is a good default) and keep
dedupeon. Each run then returns only notices you have not seen before. - Connect the dataset to your CRM, a Slack/e-mail integration, or read it via the Apify API. The dataset has a ready-made table view.
Tips
- Run without keywords first to see the volume, then filter.
- CPV filtering is stricter than keyword filtering: a notice with no published CPV code
is dropped when
cpvPrefixesis set. Use keywords if you would rather over-collect. publishedWithinDaysis the lookback window; on a daily schedule 2–3 days is enough and keeps the run fast and cheap.- If a run returns nothing, check the log: it prints how many notices each filter removed.
How much does it cost?
This Actor uses pay-per-event pricing. You are charged for the notices it actually delivers to your dataset — nothing else. Starting the Actor, failed sources, filtered-out notices and duplicates are all free.
| Event | When it fires | Planned price |
|---|---|---|
tender-notice | Once per tender notice successfully pushed to the dataset | $0.004 per notice |
There are no other events — no per-run, per-page or per-request charges.
Examples at the planned price:
| Scenario | Notices per run | Cost per run | Monthly (daily run) |
|---|---|---|---|
Focused niche (CPV 72, one Bundesland) | ~10 | $0.04 | ~$1.20 |
| Broad IT feed across Germany | ~60 | $0.24 | ~$7.20 |
Everything, no filters, maxItems: 200 | 200 | $0.80 | ~$24 |
Apify platform usage (compute units) is billed separately by Apify. The Actor is HTTP-only — no browser — and runs comfortably in 256–512 MB.
If you set a maximum cost limit for a run, the Actor stops gracefully as soon as the limit is reached: everything already pushed is kept and a warning is written to the log.
Input
| Input | Type | Default | Description |
|---|---|---|---|
sources | array | ["ted","bund","dtvp","evergabe"] | Which portals to query. |
keywords | string[] | [] | Case-insensitive substrings matched against title, buyer and description. OR semantics; empty (the default) = keep all. |
excludeKeywords | string[] | [] | Drop a notice if it contains any of these. |
cpvPrefixes | string[] | [] | Keep only notices with a CPV code starting with one of these, e.g. ["72","48"]. Notices with no CPV code are kept regardless. |
regions | string[] | [] | Keep only these Bundesländer, e.g. ["Bayern"]. |
publishedWithinDays | integer | 7 | Lookback window in days (1–90). |
onlyOpen | boolean | true | Drop notices whose deadline has passed. Unknown deadlines are kept. |
maxItems | integer | 200 | Hard cap on pushed notices per run. |
dedupe | boolean | true | Skip notices already returned by earlier runs. |
maxSeenIds | integer | 20000 | How many IDs the dedupe store keeps. |
proxyConfiguration | object | none | Optional Apify Proxy configuration. |
Example input:
{"sources": ["ted", "bund"],"keywords": ["Software", "IT-Dienstleistung", "Cloud"],"excludeKeywords": ["Reinigung"],"cpvPrefixes": ["72", "48"],"regions": ["Bayern", "Baden-Württemberg"],"publishedWithinDays": 7,"onlyOpen": true,"maxItems": 200,"dedupe": true}
Output
{"id": "ted:00512345-2026","source": "ted","title": "Rahmenvertrag über IT-Dienstleistungen für die Stadtverwaltung München","buyer": "Landeshauptstadt München, IT-Referat","description": "Gegenstand der Ausschreibung ist ein Rahmenvertrag über Beratungs- und Entwicklungsleistungen im Bereich Softwareentwicklung, Cloud-Migration und Betrieb für die Landeshauptstadt München über eine Laufzeit von vier Jahren.","cpvCodes": ["72000000", "72200000"],"procedureType": "open","region": "Bayern","country": "DE","publishedAt": "2026-08-28T00:00:00.000Z","deadlineAt": "2026-10-05T00:00:00.000Z","estimatedValue": 2450000,"currency": "EUR","noticeUrl": "https://ted.europa.eu/de/notice/-/detail/00512345-2026","documentsUrl": "https://ted.europa.eu/de/notice/00512345-2026/pdf","sourceUrl": "https://ted.europa.eu/de/notice/-/detail/00512345-2026","scrapedAt": "2026-09-02T10:00:00.000Z"}
The run also writes a RUN_SUMMARY record to the default key-value store with the number
of pushed, duplicate and filtered notices, a per-source breakdown, and the list of sources
that failed.
FAQ & support
Which sources are reliable?
TED is an official, documented and key-free JSON API — it is the most reliable and the
most complete source. service.bund.de is scraped from its public search (RSS first, HTML
as a fallback) and is reliable but markup-dependent. DTVP and evergabe are best-effort:
their endpoints are undocumented and may change without notice. If they return nothing,
the run logs a warning and continues. See NOTES.md for the exact assumptions.
Does it cover every German tender? No, and no single source does. Below-threshold notices in particular are spread over dozens of state and municipal platforms. This Actor covers the EU-wide (TED) and federal (bund.de) publications plus two large commercial platforms. Treat it as a high-coverage monitor, not a legally complete register.
Why is estimatedValue so often null?
Because most German notices simply do not publish a contract value. The Actor never
guesses — a missing value stays null.
Why did a notice I expected get filtered out?
Check the log: it prints a per-source breakdown of drop reasons (keywords, cpv,
region, publishedWithinDays, deadlinePassed), plus a final RUN_SUMMARY line with
per-source counts. Note that cpvPrefixes never drops a notice that published no CPV
code at all — the German national portals frequently omit it — so the usual culprit is
keywords or publishedWithinDays.
Why did the second run return nothing?
That is deduplication working as intended — the notices were already delivered. Set
dedupe: false to get the full result set again.
How do I reset the deduplication memory?
Delete the SEEN record from the Actor's default key-value store, or run once with
dedupe: false.
Do I need a proxy? No. All four sources are queried over plain HTTPS with no authentication. A German proxy can help if a portal rate-limits a large run.
Is scraping these portals legal? The Actor reads only publicly accessible pages and an official open API, at a modest request rate. You are responsible for how you use the data. It never collects personal data beyond the contracting-authority contact information the portals publish themselves.
Something broke / I need another portal.
Open an issue on the Actor page. Portal markup changes are the usual cause; the parsers
are written defensively with fallbacks, and NOTES.md lists exactly what to re-verify.