# CEE Public Tenders API – Official Prozorro & TED (`enterprising_hamster/cee-public-tenders`) Actor

One unified feed of public tenders from Czechia, Slovakia, Hungary and Ukraine (Prozorro, Slovak Vestník, TED): CPV, value, deadline, status, only-new alerts. Export CSV, JSON or Excel.

- **URL**: https://apify.com/enterprising_hamster/cee-public-tenders.md
- **Developed by:** [Kamil Kaczmarek](https://apify.com/enterprising_hamster) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 tenders

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## CEE Public Tenders API – Official Prozorro & TED

**CEE public tenders API**: get **public tenders from Czechia, Slovakia, Hungary and Ukraine** in one unified feed from official open data — Ukraine's **Prozorro** API, the Slovak **Vestník verejného obstarávania** (Public Procurement Journal) open data, and the EU's **TED** (Tenders Electronic Daily). Every notice becomes the same record: title, contracting authority, estimated value and currency, CPV codes, publication date, submission deadline, status, country and a link to the source. Filter by CPV and keywords, keep only tenders still open for bids, and schedule **only-new mode** to receive each tender once. Contact persons, e-mails and phone numbers are removed. Export CSV, JSON or Excel. Polski opis: **przetargi publiczne** z Czech, Słowacji, Węgier i Ukrainy (Prozorro, Vestník, TED) w jednym formacie — CPV, wartość, termin, status; bez danych kontaktowych osób.

### What data can you get

Every row has the same fields, whatever the country:

| Field | Meaning |
| --- | --- |
| `id`, `country`, `countryName`, `sourceId` | Stable id such as `UA:21ad92f0…` or `CZ:729969-2026`, ISO country code, source identifier |
| `noticeKind`, `status`, `statusOriginal` | `tender` / `award` / `correction` / `cancellation` / `planning` / `other`; `open` / `closed` / `awarded` / `cancelled` / `unsuccessful` / `unknown`; the source's own status or notice type |
| `title`, `headlineEnglish` | Title in the original language; for TED also the English headline (country – CPV category – title) |
| `buyer` | Contracting authority: `name`, `nationalId` (IČO / EDRPOU when published), `city` |
| `estimatedValue`, `currency` | Estimated value of the procedure, or the sum of published lot estimates in one currency |
| `cpvCodes`, `mainCpv`, `contractNature`, `procedureType` | CPV codes (8 digits, main first), supplies/services/works, procedure code |
| `publicationDate`, `submissionDeadline` | `YYYY-MM-DD`; earliest bid deadline in ISO 8601 with offset (or a date when the source gives no time) |
| `url` | The tender on Prozorro, the Slovak procurement office (ÚVO) site or TED |
| `source`, `sourceCoverage`, `licence`, `licenceUrl`, `retrievedAt`, `processingNote` | Attribution required by the source licences |

With `includeDetails` you also get `description`, `lots` (title, estimated value, currency, CPV), `placesOfPerformance` (NUTS codes or Ukrainian regions), `documentsUrl`, `submissionUrl`, `noticeTypeOriginal`, `euFunded` and `textTruncated`.

#### Sources and coverage

| Country | Source | Coverage | Licence |
| --- | --- | --- | --- |
| 🇺🇦 Ukraine | [Prozorro public API](https://public-api.prozorro.gov.ua/api/2.5/tenders) | All competitive procedures (open, below-threshold, price quotation…); direct awards (reporting, negotiation) excluded | Ukrainian open data terms: free reuse, including commercial, with a link to the source ([data.gov.ua](https://data.gov.ua/dataset/f9c0acdb-23c5-4a2d-b549-9868df8ca927)) |
| 🇸🇰 Slovakia | Vestník verejného obstarávania, Úrad pre verejné obstarávanie, via [data.slovensko.sk](https://data.slovensko.sk) | Every notice of the national journal, including below-EU-threshold calls; bulletins appear in the catalogue a few days after their date | CC BY 4.0 |
| 🇨🇿 Czechia | [TED Search API](https://docs.ted.europa.eu/api/latest/index.html) | Notices published on TED (above EU thresholds plus voluntary publications) | Free reuse under Commission Decision 2011/833/EU ([TED legal notice](https://ted.europa.eu/en/legal-notice)) |
| 🇭🇺 Hungary | TED Search API | Notices published on TED (above EU thresholds plus voluntary publications) | Same as above |

Czech and Hungarian below-threshold tenders are not included: their national systems do not offer an open machine interface that allows this kind of reuse (see FAQ).

### How to use

1. Pick the countries.
2. Set the window with `lastDays` and, optionally, `cpvCodes` and `keywords`.
3. Keep `onlyOpen` on to see only tenders you can still bid on, or turn it off for awards and history.
4. Run the Actor and export the dataset (JSON, CSV, Excel) or read it through the Apify API.

```json
{
  "countries": ["CZ", "SK", "HU", "UA"],
  "lastDays": 14,
  "cpvCodes": ["72000000-5", "48000000-8"],
  "includeDetails": true,
  "maxItems": 50
}
```

Daily construction monitor for Slovakia, delivering every tender once:

```json
{ "countries": ["SK"], "lastDays": 3, "cpvCodes": ["45000000-7"], "onlyNew": true, "stateKey": "sk-construction", "maxItems": 200 }
```

More inputs are in `examples/`.

### Input

IT / software tenders in all four countries, last 14 days, with details:

```json
{
  "countries": ["CZ", "SK", "HU", "UA"],
  "lastDays": 14,
  "cpvCodes": ["72000000-5", "48000000-8"],
  "includeDetails": true,
  "maxItems": 50
}
```

Daily construction monitor for Slovakia (each tender once):

```json
{ "countries": ["SK"], "lastDays": 3, "cpvCodes": ["45000000-7"], "onlyNew": true, "stateKey": "sk-construction", "maxItems": 200 }
```

| Field | Default | Meaning |
| --- | --- | --- |
| `countries` | all four | `CZ`, `SK`, `HU`, `UA` |
| `lastDays` | `7` | Publication window, 1–90 days back from now. Slovakia counts the day the bulletin was released as open data. |
| `onlyOpen` | `true` | Only calls for competition whose submission deadline is in the future |
| `keywords` | `[]` | Any of these words in the title, description or lot titles, case- and accent-insensitive, in the source language |
| `cpvCodes` | `[]` | CPV codes or prefixes: `45000000-7` matches every `45…` code, `7226` matches `72260000` |
| `includeDetails` | `false` | Add description, lots, places, links and EU-funding flag |
| `maxItems` | `10` | Maximum rows **per country**, 1–10,000 |
| `onlyNew` | `false` | Skip, and do not charge, tenders delivered by earlier runs with the same `stateKey` |
| `stateKey` | `default` | Name of the remembered set of delivered tenders |
| `maxRequestsPerSecond` | `3` | Polite rate limit per source, 0.2–5 |

### Output

```json
{
  "id": "CZ:729969-2026",
  "country": "CZ",
  "countryName": "Czechia",
  "sourceId": "729969-2026",
  "noticeKind": "tender",
  "status": "open",
  "statusOriginal": "cn-standard",
  "title": "Softwary využívající algoritmy umělé inteligence pro klinickou praxi",
  "headlineEnglish": "Czechia – Medical software package – Softwary využívající algoritmy umělé inteligence pro klinickou praxi",
  "buyer": { "name": "Fakultní nemocnice u sv. Anny v Brně", "nationalId": null, "city": "Brno" },
  "estimatedValue": 3700000.0,
  "currency": "CZK",
  "cpvCodes": ["48180000", "72263000", "50324100"],
  "mainCpv": "48180000",
  "contractNature": "supplies",
  "procedureType": "open",
  "publicationDate": "2026-10-21",
  "submissionDeadline": "2026-11-20T10:00:00+01:00",
  "url": "https://ted.europa.eu/en/notice/-/detail/729969-2026",
  "source": "TED – Tenders Electronic Daily, Publications Office of the European Union",
  "licence": "Free reuse under Commission Decision 2011/833/EU; credit TED as the source",
  "retrievedAt": "2026-10-21T19:10:00Z"
}
```

`sourceCoverage`, `licenceUrl` and `processingNote` are omitted above for brevity.

### Pricing (pay per event)

| Event | Price (USD) | When |
| --- | --- | --- |
| `tender` | 0.003 | Each delivered row in the unified schema |
| `tender-with-details` | 0.006 | Each delivered row when `includeDetails` is on |

100 open tenders cost $0.30, or $0.60 with details. Each row is charged exactly once. Tenders skipped by `onlyNew` and tenders removed by your filters are not charged. Set a maximum charge per run in Apify to cap spending; the Actor stops cleanly when it is reached.

### Use cases

- **B2G lead generation**: suppliers find tenders in four markets by CPV code with one input and one schema.
- **Tender alerts**: schedule a daily run with `onlyNew` and push new tenders to e-mail, Slack, Google Sheets or a CRM through webhooks or integrations.
- **Market research**: compare demand and estimated values across CEE countries by CPV, buyer and procedure type.
- **Ukraine reconstruction and supply**: follow Prozorro procedures next to EU-member tenders in the same feed.
- **AI agents and RAG**: give an agent current, structured procurement data through the Apify API or MCP server.

### FAQ

**Is there an API for CEE / Czech, Slovak, Hungarian and Ukrainian public tenders?** Official open interfaces exist separately: Prozorro public API (Ukraine), Slovak Vestník open data on data.slovensko.sk, and the TED Search API (Czechia and Hungary above EU thresholds). This Actor turns those live sources into **one unified, filterable table** callable from the Apify API, with CSV/JSON/Excel export.

**How do I export CEE public tenders to CSV or Excel?** Pick countries, `lastDays`, optional CPV/keywords, set Max tenders per country, run the Actor, then download the dataset as CSV or Excel from the run page or via the Apify API.

**Do you include contact persons, e-mails or phone numbers?** No. Contact persons, their e-mails and phones, bidders and winners are never read into the output. E-mails and phones in free text are replaced with `[redacted]`.

**What is the difference vs TED-only scrapers or single-country Prozorro/NEN/EKR scrapers?** TED-only actors cover EU publications; country scrapers cover one portal. This Actor is the Apify Store entry for a **unified CZ+SK+HU+UA feed** from official Prozorro + Slovak Vestník open data + TED, with CPV filters and only-new alerts, pay-per-event.

**Where does the data come from?** Only from official open interfaces, read live during each run: the Prozorro public API (Ukraine), the Slovak national open data catalogue data.slovensko.sk (bulletins of the Vestník verejného obstarávania published by the Úrad pre verejné obstarávanie) and the TED Search API of the Publications Office of the EU (Czechia, Hungary). No login, no API key and no website scraping.

**Is reuse allowed?** Prozorro data is open data under Ukrainian law: anyone may copy, publish and use it, including commercially, with a mandatory reference to the source. The Slovak journal datasets are published under CC BY 4.0. TED notices can be freely reused for commercial or non-commercial purposes under Commission Decision 2011/833/EU. Every row carries `source`, `licence`, `licenceUrl`, `url`, `retrievedAt` and `processingNote`; keep them when you republish the data.

**Why TED for Czechia and Hungary?** The Czech rules for NIPEZ APIs reserve the web APIs for normal user interaction, and the Czech open data of the public procurement register is released monthly. The Hungarian EKR portal disallows automated access in its robots.txt. TED is the official EU publication of the same notices above the EU thresholds and has an anonymous public API meant for reuse. Below-threshold Czech and Hungarian tenders are therefore not covered.

**What personal data is removed?** The Actor builds every row from an explicit list of fields. Contact persons, their e-mails and phones, bidders and winners are never read into the output. E-mail addresses and phone numbers in free text are replaced with `[redacted]`, and so is a capitalised first and last name written right before them. Other personal names inside free text cannot be removed reliably. `buyer` is the contracting authority as published by the source.

**How fresh is the data?** Prozorro and TED are read live. Slovak bulletins are taken from the open data catalogue, where they usually appear within a few days of their date.

**How does `onlyOpen` decide?** Prozorro tenders in the enquiry or tendering phase are open. For TED and Slovak notices, a call for competition is open while its earliest submission deadline is in the future. Corrections are not treated as open tenders.

**Does `onlyNew` detect updates?** No. It remembers tender ids (most recent 50,000 per `stateKey`), so a changed tender is not delivered again. Runs sharing a `stateKey` must not overlap.

**Rate limits?** At most 3 requests per second per source by default, with retries, exponential backoff and a descriptive User-Agent. The TED fair-usage limit is 700 requests per minute; a run uses a few TED requests per 100 notices.

### Integrations

Start runs and read datasets with the Apify API and clients, schedule daily monitors, send results onward with webhooks and integrations, and let AI agents call the Actor through the Apify MCP server.

### Development

```bash
python -m pytest -q                                   # offline tests, network blocked
apify run --input-file examples/smoke-default.json    # local run, no login needed
examples/run-local-ppe.sh                             # local run with simulated pay-per-event prices
python -m tools.probe UA SK                           # live check of the sources without Apify
python -m tools.record_fixtures                       # refresh anonymized test fixtures from the live sources
```

`examples/run-local-ppe.sh` sets `ACTOR_TEST_PAY_PER_EVENT=true` and `APIFY_ACTOR_PRICING_INFO` from `examples/pricing_info.local.json`.

### Disclaimer

Unofficial tool. Not affiliated with or endorsed by Prozorro, the Ukrainian Ministry of Economy, the Slovak Public Procurement Office (ÚVO), the Czech Ministry for Regional Development, the Hungarian Public Procurement Authority or the Publications Office of the European Union. Always check the tender at its source before you bid.

### 🇵🇱 Po polsku

**Przetargi publiczne z Czech, Słowacji, Węgier i Ukrainy w jednym, wspólnym formacie.** Aktor pobiera dane z oficjalnych, otwartych źródeł: Prozorro (Ukraina), dane otwarte Vestníka verejného obstarávania (Słowacja) i TED (Czechy, Węgry; tylko ogłoszenia publikowane w TED, czyli głównie powyżej progów UE). Każdy rekord ma tytuł, zamawiającego (instytucję), wartość szacunkową i walutę, kody CPV, daty, status, kraj i link do źródła.

**Wejście:** `countries`, `lastDays` (1–90), `onlyOpen` (domyślnie tylko otwarte), `keywords`, `cpvCodes` (prefiksy CPV), `includeDetails`, `maxItems` (na kraj), `onlyNew` + `stateKey` (tylko nowe od poprzedniego przebiegu).

**Dane osobowe:** osoby kontaktowe, e-maile, telefony, oferenci i wykonawcy nie trafiają do wyniku; e-maile i telefony w treści są zamieniane na `[redacted]`.

**Cennik:** `tender` 0,003 USD za rekord, `tender-with-details` 0,006 USD za rekord ze szczegółami.

# Changelog

This Actor's version history is a separate document: https://apify.com/enterprising_hamster/cee-public-tenders/changelog.md

# Actor input Schema

## `countries` (type: `array`):

Countries to collect. Each country is fetched from its own official source and normalized into the same schema.

## `lastDays` (type: `integer`):

Window of publication dates, counted back from now. Slovakia uses the date a bulletin was released as open data.

## `onlyOpen` (type: `boolean`):

Keep only calls for competition whose submission deadline is still in the future. Turn off to also get awards, cancellations, corrections and closed tenders.

## `keywords` (type: `array`):

Optional. Keep tenders whose title, description or lot titles contain any of these words (case- and accent-insensitive, in the source language, e.g. software, stavba, építés, ремонт).

## `cpvCodes` (type: `array`):

Optional. CPV codes or prefixes; 45000000-7 matches every code starting with 45, 7226 matches 72260000 etc. A tender matches when any of its CPV codes starts with any prefix.

## `includeDetails` (type: `boolean`):

Add description, lots with values and CPV codes, places of performance (NUTS or region), document and submission links and EU-funding flag. Charged as tender-with-details.

## `maxItems` (type: `integer`):

Upper limit of dataset items for each selected country.

## `onlyNew` (type: `boolean`):

Skip (and do not charge) tenders already delivered by a previous run with the same state key. Use with a schedule for daily alerts.

## `stateKey` (type: `string`):

Name of the remembered set of delivered tenders. Use different keys for different monitors.

## `maxRequestsPerSecond` (type: `number`):

Polite rate limit per source. Defaults to 3.

## Actor input object example

```json
{
  "countries": [
    "CZ",
    "SK",
    "HU",
    "UA"
  ],
  "lastDays": 7,
  "onlyOpen": true,
  "keywords": [],
  "cpvCodes": [],
  "includeDetails": false,
  "maxItems": 10,
  "onlyNew": false,
  "maxRequestsPerSecond": 3
}
```

# Actor output Schema

## `results` (type: `string`):

Unified tender records stored in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "countries": [
        "CZ",
        "SK",
        "HU",
        "UA"
    ],
    "lastDays": 7,
    "keywords": [],
    "cpvCodes": [],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("enterprising_hamster/cee-public-tenders").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "countries": [
        "CZ",
        "SK",
        "HU",
        "UA",
    ],
    "lastDays": 7,
    "keywords": [],
    "cpvCodes": [],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("enterprising_hamster/cee-public-tenders").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "countries": [
    "CZ",
    "SK",
    "HU",
    "UA"
  ],
  "lastDays": 7,
  "keywords": [],
  "cpvCodes": [],
  "maxItems": 10
}' |
apify call enterprising_hamster/cee-public-tenders --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,enterprising_hamster/cee-public-tenders"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/khtfCFz0jPNdG3niP/builds/fPatEu61MH7AtE8c8/openapi.json
