German public tenders as data: oeffentlichevergabe.de, service.bund.de, DTVP and the missing Handelsregister API
Germany has a national procurement notice service, oeffentlichevergabe.de, with a daily open-data export (CC0, no key) that includes below-threshold notices; there is no comparable free API for the commercial register. Source: Arcadium Data, data as of .
German procurement is decentralised: thousands of buyers (federal ministries, states, municipalities, utilities) post on many e-tendering platforms such as DTVP, evergabe-online, Vergabe24 or the state portals, and each platform has its own search. Scraping those one by one is a project of its own. Since eForms-DE started in late 2023, notices from all of them flow into one federal service, and that service has a machine-readable export.
This guide explains the export, how it relates to TED and the older service.bund.de, what to do with the personal-data and duplicate traps, and why the company side of German data is harder.
The official route: the federal notice service export
What the service is
The Bekanntmachungsservice at oeffentlichevergabe.de (Datenservice Öffentlicher Einkauf) takes every German notice in the eForms-DE format, above and below the EU thresholds, and offers it for download. The older service.bund.de listed federal notices and is the site many tutorials still point to; for bulk data use the newer service. DTVP and similar platforms are where buyers publish and where bidders download documents; they are not the place to collect data from, and each has its own terms of use.
The export
GET https://oeffentlichevergabe.de/api/notice-exports?pubDay=YYYY-MM-DD&format=csv.zip is anonymous. It returns one zip of about 19 CSV tables keyed by notice identifier and version, around 0.8 MB for a day. format=eforms.zip returns the original eForms XML, around 4 MB a day. History starts in December 2023. The CSV tables hold buyers, lots, CPV codes, values and winners but not the tender deadline; that sits in the XML, in the TenderSubmissionDeadlinePeriod element.
curl
curl -s -o notices-2026-10-23.zip "https://oeffentlichevergabe.de/api/notice-exports?pubDay=2026-10-23&format=csv.zip"
unzip -l notices-2026-10-23.zip
Python
import io, zipfile
import requests
r = requests.get("https://oeffentlichevergabe.de/api/notice-exports",
params={"pubDay": "2026-10-23", "format": "csv.zip"}, timeout=120)
r.raise_for_status()
with zipfile.ZipFile(io.BytesIO(r.content)) as z:
for name in z.namelist():
print(name, z.getinfo(name).file_size)
# tables join on noticeIdentifier + noticeVersion
Traps
- Versions. A corrected notice arrives as a new version of the same identifier. Keep the highest version.
- TED overlap. A notice with an EU-directive legal basis (CELEX ids like
32014L0024) is also in TED under the same procedure UUID. Roughly 390 of 1,040 notices on a typical weekday are national only (VOB/A, UVgO, VOL). - Natural persons. The tables flag winners that are natural persons (
organisationNaturalPerson). Drop those rows entirely. - Frameworks. A framework value is a ceiling, not spend.
Why there is no Handelsregister API
Winners come with a name and sometimes a register number, so people ask for the commercial register. Germany has no free bulk or REST API for the Handelsregister: the public portal is a search interface with usage terms that rule out mass automated queries, and structured extracts are paid. Open German company data comes from elsewhere (the winners' own legal notice pages, the LEI register, VAT validation through VIES; see the registration number guide).
Reading the tables
The CSV tables mirror the eForms business terms: one table for the notice, one for organisations (buyer, winner, with a NUTS code and a legal-person flag), one for lots, one for the lot results and tenders, one for classification codes and so on. Join them on notice identifier and version, then on the lot identifier. The buyer's region comes from its NUTS code (DE has 16 states at level 1 and about 400 districts at level 3), which makes regional views easy. Values are in the notice currency; the vast majority are EUR. Frameworks and dynamic purchasing systems are flagged, and a framework value is a maximum, not spend.
A daily loop
Request yesterday's export after the morning, unzip in memory, keep only the highest version of each identifier, drop EU-directive notices if you read TED, and upsert. Re-request the previous three days too: a notice can be published on one day and corrected on the next, and the export for a publication day is built from what was published that day. The files are small, so the cost is mostly your parser.
Matching winners to companies
German winners come with a legal name, an address and often a register court and number in the notice; many also state a website or email domain in the organisation table. A good join uses, in order: a stated website; the name plus postal code; the register number with its court (HRB 12345 at Amtsgericht Munich is unique only together with the court). The legal form (GmbH, GmbH & Co. KG, AG, SE, e.V.) is in the name and helps to separate companies from associations and public bodies. Because there is no open register API, the notice itself is often the best open source for the registration number; our guide on finding VAT and registration numbers covers the other routes, including the VAT check through VIES.
Two more limits to keep in mind: the export is organised by publication day, not by contract date, so a question like "what was awarded in March" needs the award date from the notice, and winners marked as natural persons are withheld, so winner counts are lower bounds. The cut-off for the first eForms-DE notices is December 2023; older German notices live in TED only.
Licence: CC0 for the export. The public notice page is https://oeffentlichevergabe.de/api/notices/<id>?format=pdf¬iceVersion=<n>.
The fast route: German contracts with winners and end dates
Arcadium Data unzips the daily export, keeps the highest version, merges TED and national notices, drops natural-person winners, and adds the winner's website when the notice or a register shows one. Contract end dates and expected re-tenders for German buyers are open without a key:
Calls on this page work without a key from one IP (10 requests a minute, 100 a day, short answers, point lookups). A free key lifts the limits: sign up. Routes, parameters and fields: OpenAPI.
curl
curl -s "https://api.arcadiumdata.io/v1/tenders/expiring?country=DE&limit=1"
Python
import requests
data = requests.get("https://api.arcadiumdata.io/v1/tenders/expiring?country=DE&limit=1", timeout=30).json()
for n in data["data"]:
print(n["title"], n["buyer"]["name"], n["endOn"], n["expectedRetender"])
TypeScript
const res = await fetch('https://api.arcadiumdata.io/v1/tenders/expiring?country=DE&limit=1');
const data = (await res.json()) as { data: { title: string; buyer: { name: string }; endOn: string; value: { eur: number } }[] };
for (const n of data.data) console.log(n.title, n.buyer.name, n.endOn, n.value.eur);
Response (abridged)
{
"count": 1,
"data": [{
"id": "ted:131412-2026",
"title": "Germany – Electricity supply installations – Kreishaus Osnabrück / Umfassende Gebäudesanierung ...",
"buyer": { "name": "Landkreis Osnabrück - Abt. 13.3 Zentrale Vergabestelle", "country": "DE", "nuts": "DE944" },
"holders": [{ "name": "Tippkötter GmbH & Co. KG", "domain": "tippkoetter.de" }],
"value": { "eur": 518786, "basis": "award" },
"endOn": "2026-10-25", "endBasis": "concluded_plus_duration"
}]
}
The one-year German market view (about 89,000 awards, 45 billion EUR) is GET /v1/tenders/markets?country=DE. Notice search needs a free key. Sector pages: German tenders.
Comparison
| Federal export | Platforms (DTVP and others) | Arcadium Data | |
|---|---|---|---|
| Key | None | Per platform, terms restrict bots | None for summaries |
| Coverage | All eForms-DE notices | Their buyers only | Federal export plus TED |
| Format | 19 CSV tables or eForms XML | HTML | One flat schema |
| Below thresholds | Yes | Yes | Yes |
| Winner websites | No | No | Where known |
| Licence | CC0 | Terms of each site | Source URL kept |
Get the data without the plumbing
Arcadium Data serves these datasets from one REST API and one MCP server, with sources, licences and dates on every answer. No key is needed to try the routes in this guide.
Related
- TED API guide
- Find a VAT or registration number from a website
- Find public contracts that end soon
- German tenders
Sources
Last updated 2026-10-25. This guide is ours and independent of the organisations it describes. Found a mistake? Tell us and we correct it.
Questions
Is there an API for German public tenders?
There is a daily export at oeffentlichevergabe.de/api/notice-exports, free and anonymous, as CSV tables or eForms XML. It covers German eForms notices above and below the EU thresholds from December 2023.
What is the difference between service.bund.de and oeffentlichevergabe.de?
service.bund.de is the older federal listing that many guides still cite. oeffentlichevergabe.de is the current national notice service with the open-data export.
Can I scrape DTVP?
DTVP is a commercial e-tendering platform. Read its terms of use before any automated access; its notices already reach the federal service, so the export is the cleaner source. Use the export instead.
Does Germany have a Handelsregister API?
No free bulk or REST API. The portal is a search interface with usage limits and paid extracts. Use legal notice pages, LEI and VIES for open company data.
How do I avoid counting a TED notice twice?
Skip export notices whose legal basis is an EU directive, because they are also in TED under the same procedure id. Keep the national-law notices.
Cite as: Arcadium Data, "German public tenders as data: oeffentlichevergabe.de, service.bund.de, DTVP and the missing Handelsregister API", https://arcadiumdata.io/guides/germany-public-tenders-data-oeffentlichevergabe/, data as of 2026-10-25.