Skip to content

Find public tenders worth bidding on

Every Czech public buyer has to publish its tenders on a registered buyer profile (profil zadavatele), and every profile must also serve them as XML in one national format. The portals differ — Tender Arena, E-ZAK, E-ZAKAZKY, Vhodné uveřejnění, NEN and more — but the format does not, so all of them can be read as a single feed.

That matters for a builder because the work it wants is split across dozens of buyers: in Prague alone, 57 city districts, the Magistrát, and the property companies the districts run their buildings through. A tender is often open for less than six weeks.

Enable Public Tenders on your workspace under Settings → Connections → Public Registers. There is nothing to connect: the data is public and needs no account or key.

Out of the box the step reads a Prague list: every city district and the Magistrát whose export can be read, plus the districts’ property companies. It is kept as a record, not just a list. For each buyer, Routario notes whether its export answers and whether the export names that buyer’s own registration number. A few buyers cannot be read, and the record says why:

  • the export answers with a web page instead,
  • the certificate belongs to a different site,
  • no profile is registered at all.

A few portals still export an older version of the national format — CENT’s profilzadavatele-vz.cz, used by Praha 7, Libuš and Zbraslav. It is read too, but it states no kind of work, so a tender’s kind there is judged from its title.

The watchlist is a workspace setting, public_tenders.watchlist. Leave it empty to use that list, or set it to one buyer per line:

Městská část Praha 8 | 00063797 | https://ezak.praha8.cz/profile_display_2.html/XMLdataVZ

A list of a few hundred buyers — a city’s own organisations, its districts’ property companies and schools — reads better as a table than as a setting. Keep one row per buyer with the columns name, ico, url (the export address) and profile_url, and name the table in the step’s Or read the watchlist from a table setting. A row without a url is skipped, so the buyers that cannot be read stay in the same table with a note saying why, where anyone can see them. A named table with no row to read fails the step instead of quietly reading the Prague list.

The registration number is optional, but it is what lets Routario refuse an export that belongs to someone else. Several buyers can share one portal, so an address that answers is not proof on its own. When a buyer moves its profile, the step finds the new address in the national register, reads it, and says so in failures so you can update the line.

A ministry, the road and rail authorities or a state hospital build in your city too, and none of them is one of its own buyers. Name the region in the step’s Also read the EU journal for tenders in these regions setting — a NUTS code, CZ010 for Prague — and the step also asks the EU’s Official Journal for every open tender located there. A tender from a buyer already on your list is skipped, because its profile returns it with more detail. These rows carry source: ted, the value the notice states and a link to it.

Only tenders above the EU thresholds must be published in the journal — for construction work about €5.5 million, some 135 million crowns — plus the smaller ones a buyer chooses to publish there. Smaller tenders state no place anywhere a machine can read, so below the threshold a tender is found only through its buyer’s profile.

The Read public tenders step returns one item per tender lot. Each item carries:

  • the buyer and the title,
  • whether it is works, services or supplies — a tender whose CPV code is construction work (division 45) counts as works even when the buyer ticked supplies,
  • the bid deadline — taken from the tender’s Věstník notices when the portal’s export leaves it out (E-ZAKAZKY never sends one), so an open tender there is not read as closed,
  • a link you can open — the most specific page there is: the portal’s own tender page, else the tender’s notices in the Věstník when it has an evidence number, else the buyer’s profile,
  • once awarded, a link to the signed contract in the state register,
  • every published document, and document_url — where a person downloads the tender documentation, also when the step cannot read it itself,
  • how many bids it drew,
  • once awarded, the winner and the contract price.

Its signal says where the tender stands: open_tender, awarded, cancelled or closed.

The export never says what an open tender is worth. The estimated value is written only in the tender documentation, and so are the scope and the qualification bar. For every open tender the step downloads that documentation into Memory and hands it on as document_ref. It follows portals’ download pages to the actual file, and unpacks a zipped bundle to its PDF.

An open tender published in the EU’s Official Journal also brings what its notice there states — notice_value_czk and notice_scope, with notice_url to open it — whether or not its documentation was read, because documentation often leaves the value out. On E-ZAK portals the tender’s own page states it too, and a tender of one lot takes it as page_value_czk. Only an unambiguous answer counts — one journal notice for the tender, lots that line up with the tender’s, Czech crowns, a value above zero. A Věstník number several tenders share belongs to a dynamic purchasing system or a framework, and its value is not the job’s, so it is skipped.

Read it with an Extract step and the cz_public_tender recipe to get:

  • the estimated value without VAT,
  • what kind of building it is (school, kindergarten, housing, office, …),
  • what kind of work (energy retrofit, extension, reconstruction, …),
  • the site, the start date and the duration,
  • the references and turnover a bidder must show.

The flow that works:

  1. Read public tenders with Tenders published or updated in the last N days set to 3 and Kinds set to works. The window returns tenders that were published or changed, so an award or a moved deadline comes back as well.
  2. For each tender, branch on {{ tender.document_ref }}. Only a tender with stored documentation goes to Extract with cz_public_tender.
  3. Create record with source_key as the upsert key. The tender’s row then updates as it moves from open to awarded, instead of duplicating.
  4. Branch on the value read from the document, and send the ones in your range to Propose change as a new deal. The row is written before the gate, so everything stays on record either way.

Run it every morning. The shape is in the automation library as Prague public tender radar.

The export names the buyer, never the building, so a tender is placed by the flow rather than by the reader:

  1. Look the buyer up with List records in a places table of your own — one row per area you tender in, with a key (the buyer’s registration number), a name, and lat/lon. For Prague that is the 57 městské části plus the Magistrát, whose boundaries the city publishes as open data (datový podklad © IPR Praha, CC BY 4.0); another country’s regions import the same way.
  2. Geocode the site address the documentation gave — behind a branch that checks there is one. A required input that renders empty blocks the step and halts the run, so a tender without an address must not reach the geocoder at all. That pin is the building itself.
  3. Write whichever you got into lat/lon, with a column saying which — the address when it resolved, the area otherwise. A map tile over those two columns then shows every tender, and a pin never claims to be the building when it is only the district.

A buyer commissions the design of a reconstruction months before it tenders the construction, and the design tender names the building. Keep Also keep design tenders for buildings on, and those services tenders come back marked design_tender. They tell you what is coming while there is still time to prepare.

A services tender counts as one when its title names design work — projektová dokumentace, PD, studie, autorský dozor — or the supervision of the construction — správce stavby, TDS, technický dozor, BOZP — and the tender names a building. Supervision comes when the construction is already let, and is kept for who tenders it. A subject mentions the tender documentation as a matter of form, so a security, cleaning or servicing contract that only does that is not kept.

  • What kind of work it is. An Ask AI step with response_format: enum puts each tender in one of the categories a builder thinks in — new build, building reconstruction, envelope and facade, roof, building services, fit-out, public space and roads, utilities, demolition, design documentation, site supervision. Pass the options as a JSON array so multi-word categories survive as themselves. It is worth the call: half of Prague’s construction tenders turn out to be public space and roads, which a building contractor does not bid on, and the column is what lets them skip those at a glance. The category is read from the title and subject, so treat it as a sorting aid, not a fact. Design documentation and site supervision are deliberately separate: the first says a building is being drawn and its construction follows in a year or two, the second says the construction is already let and you are reading the wrong end of it.
  • A verdict of your own. Add a Yes/No column to the table — “worth bidding?” — and leave it out of the Create record step. The row is upserted every morning and only the columns that step names are touched, so a person’s Yes is never overwritten by the radar.
  • A portal that answers only with a web page, or with a certificate for a different site, cannot be read. The buyer’s record says which.
  • Tender Arena has no tender page we can link. Its pages are built in JavaScript from an id the export does not carry, so those rows link the tender’s Věstník notices instead — about two in five of them have an evidence number, and they are the larger tenders. The rest link the buyer’s profile, where the tender is one row in a list.
  • Tender Arena’s documents cannot be read automatically. Its portal hands out a tender’s documentation only after a browser check, which is bot detection and not something to get past. Those tenders arrive with document_url, the link where a person downloads the documentation in their own browser. Give the table an attachment column for it: a person attaches the downloaded PDF to the row, and a scheduled flow that reads attached documentation with the same cz_public_tender recipe fills in the values.
  • The reader reads PDFs. A tender whose only documentation is a Word file keeps its row, without the values the recipe would read.
  • A tender whose documentation cannot be read is placed at its buyer’s area, not at the building. The row says which, so the map can be read honestly.
  • A tender with no deadline anywhere cannot be called open. A small tender on E-ZAKAZKY or on the older format has no deadline in its export and no Věstník notice to take one from, so it stays listed as closed.
  • The buyer’s box is corrected only by the code. A tender filed as supplies under a code that is not construction work — a lift is CPV 42 — is not read as works.
  • Tender Arena limits how fast it may be read. The step waits between requests, so a morning run over every Prague buyer takes several minutes.