# Prozorro & TED Tenders Scraper - Ukraine & EU (`tiger19935/prozorro-ted-tenders-scraper`) Actor

Open public tenders from Ukraine (Prozorro) and all of the EU (TED) in one English dataset: CPV sector presets, values in EUR, documents, AI summaries and a monitoring mode that returns only new and changed tenders.

- **URL**: https://apify.com/tiger19935/prozorro-ted-tenders-scraper.md
- **Developed by:** [Andrew Boiko](https://apify.com/tiger19935) (community)
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.60 / 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

## Prozorro & TED Tenders Scraper - Ukraine & EU

Find **open public tenders in Ukraine (Prozorro) and the whole EU (TED - Tenders Electronic Daily)** in **one English-language dataset**: buyer, CPV category, **estimated value in EUR**, bid deadline, lots and tender documents. Pick a sector (e.g. **Ukraine reconstruction**, energy, IT, medical) or your own CPV codes, and schedule it in **"New since last run"** mode to get only fresh and changed tenders every morning - optionally with **AI summaries in English** for Ukrainian, Polish, German... notices.

### Who is it for?

- **Companies selling to governments** - construction, engineering, energy, IT, medical equipment: never miss a relevant call for tenders in Ukraine, Poland, Germany or anywhere in the EU.
- **Ukraine reconstruction players** - contractors, suppliers, consultants and international donors' implementing partners tracking Prozorro and EU-funded tenders (TED also publishes tenders for Ukraine financed by EU programmes).
- **Bid consultants and tender alert services** - feed your clients' alerts, CRM or newsletter from one clean source.
- **Market and competitor intelligence** - who buys what, for how much, in which region.

### What data do you get?

| Field | Example |
|---|---|
| `noticeId`, `source`, `url` | `prozorro:UA-2026-10-02-011503-a`, `ted:663796-2026` |
| `title`, `titleEn`, `summaryEn`, `summarySource` | original title + English title / summary (`official` or `ai`) |
| `buyerName`, `buyerId`, `buyerCountry`, `buyerCity`, `buyerRegion` | incl. Ukrainian EDRPOU code |
| `cpv[]`, `mainCpv`, `mainCpvLabelEn`, `cpvLabelsEn[]` | `45450000-6` - Other building completion work |
| `valueAmount`, `valueCurrency`, `valueEur`, `fxRateDate` | 1,875,000 UAH = €37,104 |
| `deadlineAt`, `publishedAt`, `status`, `noticeType`, `procedureType` | bid deadline, open procedure... |
| `lots[]`, `documents[]` | lot titles and values, links to tender documentation |
| `placeOfPerformance[]`, `contractNature[]` | NUTS codes / regions, works / supplies / services |
| `changeType` | `active`, or `new` / `updated` in monitoring mode |

Values are converted to EUR with the **official National Bank of Ukraine rates** of the day. CPV codes from both sources use the same format with check digits and English labels.

### How to use it

1. Choose **sources** (TED, Prozorro or both).
2. Pick **sectors** and/or enter **CPV codes** (prefixes are expanded: `45` = all construction works, `4531` = electrical installation).
3. Optionally add **keywords**, **buyer countries** (ISO codes: UKR, POL, DEU, ROU...), a **minimum value in EUR** and the **publication window**.
4. Keep **Only tenders open for bids** on to get only calls you can still bid for.
5. Click **Start**, then download JSON, CSV or Excel - or schedule it.

#### Example input - reconstruction tenders in Ukraine and Poland above €100,000

```json
{
  "sources": ["ted", "prozorro"],
  "sectors": ["reconstruction"],
  "buyerCountries": ["UKR", "POL"],
  "minValueEur": 100000,
  "publishedWithinDays": 7,
  "onlyOpen": true,
  "aiSummary": true,
  "maxItems": 200
}
```

#### Example output (one tender, shortened)

```json
{
  "noticeId": "prozorro:UA-2026-10-02-011503-a",
  "source": "prozorro",
  "url": "https://prozorro.gov.ua/en/tender/UA-2026-10-02-011503-a",
  "title": "ДК 021:2015: 45450000-6 Інші завершальні будівельні роботи (Поточний ремонт приміщень рентгенівського кабінету ...)",
  "titleEn": "Repair of X-ray room premises on the 6th floor of a polyclinic in Kyiv",
  "summaryEn": "A Ministry of Internal Affairs medical institution in Kyiv is procuring current repair works of its X-ray room. Estimated value UAH 1,875,000 excl. VAT; bids are due by 18 October 2026.",
  "summarySource": "ai",
  "buyerName": "Державна установа «Територіальне медичне об'єднання МВС України по місту Києву та Київській області»",
  "buyerId": "37027405",
  "buyerCountry": "UKR",
  "buyerRegion": "Київська область",
  "cpv": ["45450000-6"],
  "mainCpvLabelEn": "Other building completion work",
  "status": "active.tendering",
  "valueAmount": 1875000,
  "valueCurrency": "UAH",
  "valueEur": 37104,
  "fxRateDate": "2026-10-05",
  "deadlineAt": "2026-10-18T00:00:00+03:00",
  "documents": [{ "title": "Тендерна_документація ... .doc", "url": "https://public-docs.prozorro.gov.ua/get/...", "format": "application/msword" }],
  "changeType": "new"
}
```

The run summary (`OUTPUT`) lists the status and total matches per source, new/updated counts, AI summary count and warnings.

### Monitoring: new tenders every morning

Set **Mode = New since last run** and add a **schedule**. Each run returns only:

- `new` - tenders you have not received before,
- `updated` - tenders whose value, deadline, status or title changed (e.g. a deadline extension).

Add a **digest webhook** (Slack, Discord, Microsoft Teams, Make, Zapier, n8n) to receive a short list after every run. Several saved tasks (e.g. "solar-poland", "roads-ukraine") keep independent histories via **Monitor name**.

### English AI summaries

Turn on **English AI summary** and every tender without an official English text (most Prozorro and many national-language TED notices) gets a 2-3 sentence English summary and title. You can use the built-in AI (billed per summary) or **your own OpenAI-compatible API key** - then summaries are not billed by this Actor at all. Summaries use only facts from the notice; always check the original documents before bidding.

### Pricing

Pay per event - you pay only for results:

| Event | Price |
|---|---|
| Tender saved to the dataset | **$0.003** per tender ($3 per 1,000) |
| English AI summary (built-in AI only) | **$0.01** per summary |
| Digest delivered to your webhook | **$0.05** per digest (only when delivered) |

plus a small per-run start fee shown on the *Pricing* tab. Platform usage is included. **Max tenders** and your *maximum cost per run* are always respected - AI summaries are only created for tenders that fit into your budget.

*Example:* a daily monitor for one sector that finds 30 new tenders a day costs about $0.09 per day without AI, or about $0.39 with AI summaries for all of them.

### Integrations and API

Send tenders to **Google Sheets, Airtable, your CRM, Slack or e-mail** with Make, Zapier or n8n, or call the Actor from code and AI agents (Apify API, Apify MCP server).

```bash
curl -X POST "https://api.apify.com/v2/acts/<USERNAME>~prozorro-ted-tenders-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"sectors":["energy"],"buyerCountries":["UKR"],"minValueEur":50000,"maxItems":100}'
```

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("<USERNAME>/prozorro-ted-tenders-scraper").call(run_input={"cpvPrefixes": ["72"], "keywords": ["cloud"], "sources": ["ted"]})
for t in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(t["valueEur"], t["deadlineAt"], t["titleEn"] or t["title"], t["url"])
```

### FAQ

**Where does the data come from? Is it legal?** Only official open government data: the **TED Search API** of the Publications Office of the EU (reuse is free, with attribution) and **Prozorro** - Ukraine's public e-procurement system, whose data is open by law (official public API at public-api.prozorro.gov.ua plus the search used by prozorro.gov.ua). No login, no personal data beyond what buyers publish.

**Which tenders are "open for bids"?** TED: calls for competition (contract notices, competition-type prior information notices) whose submission deadline has not passed. Prozorro: procedures in the `active.tendering` stage.

**What is CPV?** The EU's Common Procurement Vocabulary - the category code of a tender (Ukraine uses the same codes as DK 021:2015). Use the sector presets or any 2-8 digit prefix.

**Why is the value empty for some tenders?** Buyers are not always required to publish the estimated value (common in TED). With a minimum value filter such tenders are skipped.

**How fresh is it?** Every run queries the sources live. TED publishes new notices every working day; Prozorro in real time.

**Something is missing?** Open an issue in the *Issues* tab - requests for more sources (e.g. national portals, award notices) are welcome.

### More tools by the same author

- [Djinni, DOU & JustJoin.it IT Jobs Scraper](https://apify.com/tiger19935/djinni-dou-justjoin-jobs-scraper): Ukrainian and Polish IT jobs in one run
- [Domain to Company Enrichment](https://apify.com/tiger19935/domain-company-enrichment): Turn domains into company profiles

# Changelog

This Actor's version history is a separate document: https://apify.com/tiger19935/prozorro-ted-tenders-scraper/changelog.md

# Actor input Schema

## `sources` (type: `array`):

TED = the official journal of EU public procurement (all EU/EEA countries plus EU-funded tenders worldwide, incl. Ukraine). Prozorro = Ukraine's national e-procurement system.

## `sectors` (type: `array`):

Ready-made CPV groups. Combined with 'CPV codes' below. Leave both empty to get all sectors.

## `cpvPrefixes` (type: `array`):

Your own CPV codes or prefixes (2-8 digits). "45" = all construction, "4531" = electrical installation, "72000000" = IT services. Sub-codes are included automatically.

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

Optional full-text keywords (any of them matches), up to 10. Use the notice language for best results, e.g. "solar", "Photovoltaik", "сонячн", "дах".

## `buyerCountries` (type: `array`):

3-letter ISO codes of the buyer's country, e.g. UKR, POL, DEU, ROU. Leave empty for all. Prozorro is used only when UKR is included (or the list is empty).

## `minValueEur` (type: `integer`):

Skip tenders below this value (converted to EUR with official National Bank of Ukraine rates). Tenders without a published value are skipped when this is set.

## `publishedWithinDays` (type: `integer`):

Only tenders published in the last N days.

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

Keep only calls for competition whose submission deadline has not passed. Turn off to include closed and awarded procedures.

## `mode` (type: `string`):

'All matching' returns every matching tender. 'New since last run' returns only tenders that are new or changed (value, deadline, status or title) since the previous run with the same filters.

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

Name for the monitoring memory, e.g. "solar-poland". Runs with the same name share it. Leave empty to derive it from the filters. Letters, digits and '-' only.

## `digestWebhookUrl` (type: `string`):

After each run, post a short digest of the found tenders here. Slack/Discord/Teams URLs get a native message; other URLs receive JSON with the items. Stored encrypted. Must start with https://.

## `aiSummary` (type: `boolean`):

Adds a 2-3 sentence English summary (and English title) to tenders that have no official English text, e.g. Prozorro tenders. Billed per summary unless you use your own OpenAI key.

## `openaiApiKey` (type: `string`):

Use your own key - AI summaries are then not billed by this Actor. Works with OpenAI or any OpenAI-compatible provider (set the endpoint below). Leave empty to use the built-in AI.

## `aiModel` (type: `string`):

Model used with your own API key (default: gpt-4o-mini). The built-in AI always uses its own model.

## `aiBaseUrl` (type: `string`):

OpenAI-compatible base URL for your own key, e.g. https://openrouter.ai/api/v1. Default: https://api.openai.com/v1.

## `includeDocuments` (type: `boolean`):

Add links to tender documentation files (up to 25 per tender).

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

Maximum number of tenders per run (newest first). You pay only for tenders you receive.

## Actor input object example

```json
{
  "sources": [
    "ted",
    "prozorro"
  ],
  "sectors": [
    "reconstruction"
  ],
  "cpvPrefixes": [],
  "keywords": [],
  "buyerCountries": [],
  "publishedWithinDays": 7,
  "onlyOpen": true,
  "mode": "all",
  "aiSummary": false,
  "includeDocuments": true,
  "maxItems": 100
}
```

# Actor output Schema

## `tenders` (type: `string`):

Tenders found in this run, newest first.

## `summary` (type: `string`):

Per-source status and totals, new/updated counts, AI summary count, exchange-rate source and warnings.

# 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 = {
    "sources": [
        "ted",
        "prozorro"
    ],
    "sectors": [
        "reconstruction"
    ],
    "publishedWithinDays": 7,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("tiger19935/prozorro-ted-tenders-scraper").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 = {
    "sources": [
        "ted",
        "prozorro",
    ],
    "sectors": ["reconstruction"],
    "publishedWithinDays": 7,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("tiger19935/prozorro-ted-tenders-scraper").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 '{
  "sources": [
    "ted",
    "prozorro"
  ],
  "sectors": [
    "reconstruction"
  ],
  "publishedWithinDays": 7,
  "maxItems": 100
}' |
apify call tiger19935/prozorro-ted-tenders-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tiger19935/prozorro-ted-tenders-scraper"
        }
    }
}
```

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/PWqR0LLqbKOpaRWLO/builds/qyF9zQxOmrey7SbKh/openapi.json
