# Prozorro Scraper (`donjuan_mime/prozorro-scraper`) Actor

Scrape Ukrainian public tenders from Prozorro (ProZorro): buyers, EDRPOU, CPV, expected value, bids, winners, contracts. Search by keyword or filters.

- **URL**: https://apify.com/donjuan_mime/prozorro-scraper.md
- **Developed by:** [Donjuan](https://apify.com/donjuan_mime) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 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.

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 Scraper: Ukrainian public tenders, buyers, bids, and winners

Prozorro Scraper collects tenders from Prozorro (also written ProZorro), Ukraine's public procurement system. For every tender you get the title, status, procedure type, expected value, the buyer with its EDRPOU code and contacts, CPV codes, key dates, the number of bids, and the winner. Turn on details to also get every item, lot, bid, award, contract, and document.

Search by keyword, filter by buyer, CPV code, region, status, procedure type, value, or date, or fetch specific tenders by their UA-... ID. You don't need an account or an API key. Download the results as JSON, CSV, Excel, XML, or HTML, or pull them into your app through the Apify API.

Tender texts come as Prozorro publishes them, which is mostly in Ukrainian.

### What can you do with Prozorro data?

- **Find tenders to bid on.** Search your keywords and CPV codes in the regions you serve, keep tenders that still accept bids, and check the deadline in `tenderPeriod.endDate`.
- **Track competitors.** See which suppliers win in your market, at what prices, and against how many bidders.
- **Research buyers.** Pull every tender of a hospital, a city council, or a ministry by its EDRPOU code and see what it buys, how often, and for how much.
- **Monitor prices.** Compare expected values with winning bids for the same CPV code across regions and over time.
- **Investigate and report.** Journalists and watchdogs can follow the money: who bought what from whom, with links to the source documents.
- **Feed a CRM or BI tool.** Schedule a daily run and send new tenders to Google Sheets, Slack, or your own database.

### What data does Prozorro Scraper extract?

| Group | Fields |
|---|---|
| Tender | internal ID, UA-... tender ID, URL, title, description, status, procurement method and type, category (goods, services, works) |
| Value | expected amount, currency, VAT included |
| Buyer | name, EDRPOU, kind, region, locality, street address, postal code, contact person, email, phone |
| Classification | main CPV code and description, all CPV codes |
| Dates | created, modified, clarifications period, bidding period, auction period, award period (ISO 8601, UTC) |
| Competition | number of bids, number of lots |
| Winner | supplier name, EDRPOU, award amount |
| Details (optional) | items with quantity, unit, CPV, and delivery place; lots; bids with bidder and price; awards with supplier and status; contracts with signing date and amount; documents with links |

### How to scrape Prozorro

1. Open the actor and go to the **Input** tab.
2. Add search queries, or leave them empty and set filters only: a buyer's EDRPOU, CPV codes, regions, statuses, a value range, or dates.
3. To fetch specific tenders, paste their UA-... IDs or prozorro.gov.ua links.
4. Set **Max tenders per search** and decide whether you need **Include details**.
5. Press **Start**. When the run finishes, open the **Output** tab or press **Export**.

### Input

| Field | Type | Description |
|---|---|---|
| `searchQueries` | array of strings | Keywords, in Ukrainian as they appear in titles. Each query is a separate search with all filters applied. |
| `buyerEdrpou` | array of strings | Buyers' 8-digit EDRPOU codes. |
| `cpvCodes` | array of strings | CPV (DK 021:2015) codes, for example `30210000-4`. |
| `regions` | array | Buyer regions, for example `lvivska` or `kyiv`. Each region is a separate search. |
| `statuses` | array | Tender statuses, for example `active.tendering` or `complete`. |
| `procurementMethodTypes` | array | Procedures, for example `aboveThreshold`, `belowThreshold`, or `reporting`. |
| `minAmount`, `maxAmount` | integer | Expected value range in UAH. |
| `dateFrom`, `dateTo` | string | Range for the start of the bidding period, `YYYY-MM-DD`. |
| `sortBy` | string | `relevance`, `newest`, `oldest`, `valueHighest`, or `valueLowest`. |
| `tenderIds` | array of strings | Specific tenders by UA-... ID. |
| `startUrls` | array | Tender page links on prozorro.gov.ua. |
| `maxItems` | integer | Tenders per search query and region. |
| `includeDetails` | boolean | Add items, lots, bids, awards, contracts, and documents. |
| `proxyCountryCode` | string | `None` for Apify datacenter proxy, or a country code for residential proxy. |

#### Input example

```json
{
  "searchQueries": ["ноутбук"],
  "cpvCodes": ["30210000-4"],
  "regions": ["lvivska", "kyiv"],
  "statuses": ["complete"],
  "minAmount": 20000,
  "sortBy": "newest",
  "maxItems": 100,
  "includeDetails": true
}
```

### Output

Every tender becomes one item in the dataset. The **Tenders** view shows the main columns, and the **Winners** view puts suppliers and award amounts first.

#### Output example

Below is a real tender with **Include details** turned on. Lists are cut to two entries, document links are shortened, and the contact person is masked here; the dataset holds the real values.

```json
{
  "id": "c609d5c6269c408283d7756b67c45098",
  "tenderID": "UA-2025-09-26-003752-a",
  "url": "https://prozorro.gov.ua/tender/UA-2025-09-26-003752-a",
  "title": "Стіл метролога в комплекті",
  "description": "Зміни до Річного плану закупівель на 2025 рік",
  "status": "complete",
  "procurementMethod": "open",
  "procurementMethodType": "belowThreshold",
  "mainProcurementCategory": "goods",
  "value": {
    "amount": 112000,
    "currency": "UAH",
    "vatIncluded": true
  },
  "buyer": {
    "name": "ВІЙСЬКОВА ЧАСТИНА А1124",
    "edrpou": "08532943",
    "kind": "defense",
    "region": "Львівська область",
    "locality": "Львів",
    "address": "вул. Творча 11",
    "postalCode": "79059",
    "contactName": "<contact person>",
    "contactEmail": "<email>",
    "contactPhone": "<phone>"
  },
  "cpv": {
    "code": "39180000-7",
    "description": "Лабораторні меблі"
  },
  "cpvCodes": [
    "39180000-7"
  ],
  "dateCreatedISO": "2025-09-26T08:00:20.150Z",
  "dateModifiedISO": "2025-10-24T09:17:50.754Z",
  "enquiryPeriod": {
    "startDate": "2025-09-26T08:00:20.150Z",
    "endDate": "2025-10-02T09:00:00.000Z"
  },
  "tenderPeriod": {
    "startDate": "2025-10-02T21:00:00.000Z",
    "endDate": "2025-10-07T21:00:00.000Z"
  },
  "awardPeriod": {
    "startDate": "2025-10-08T10:33:41.985Z",
    "endDate": "2025-10-09T07:41:23.585Z"
  },
  "numberOfBids": 2,
  "numberOfLots": 1,
  "winner": {
    "name": "ТОВАРИСТВО З ОБМЕЖЕНОЮ ВІДПОВІДАЛЬНІСТЮ \"ЛІТПОЛ-УКРАЇНА\"",
    "edrpou": "32134535",
    "amount": 100000,
    "currency": "UAH"
  },
  "items": [
    {
      "description": "Стіл метролога в комплекті",
      "quantity": 4,
      "unit": "комплект",
      "cpvCode": "39180000-7",
      "cpvDescription": "Лабораторні меблі",
      "deliveryRegion": "Львівська область",
      "deliveryLocality": "Львів",
      "lotId": "0fd823a7abaa40e6af94c1e4b667ff86"
    }
  ],
  "lots": [
    {
      "id": "0fd823a7abaa40e6af94c1e4b667ff86",
      "title": "Стіл метролога в комплекті",
      "status": "complete",
      "amount": 112000,
      "currency": "UAH"
    }
  ],
  "bids": [
    {
      "id": "3ff14f60e1a34f23ae48194f7e63e745",
      "status": "active",
      "dateISO": "2025-10-03T07:55:39.827Z",
      "tendererName": "Приватне акціонерне товариство \"УХЛ-Маш\"",
      "tendererEdrpou": "14311749",
      "amount": 104976,
      "currency": "UAH",
      "lotId": "0fd823a7abaa40e6af94c1e4b667ff86"
    },
    {
      "id": "eb4a2588875a4cdb997c4daaff059140",
      "status": "active",
      "dateISO": "2025-10-04T19:48:20.340Z",
      "tendererName": "ТОВАРИСТВО З ОБМЕЖЕНОЮ ВІДПОВІДАЛЬНІСТЮ \"ЛІТПОЛ-УКРАЇНА\"",
      "tendererEdrpou": "32134535",
      "amount": 100000,
      "currency": "UAH",
      "lotId": "0fd823a7abaa40e6af94c1e4b667ff86"
    }
  ],
  "awards": [
    {
      "id": "5f6fefd7b72d4a4388ca87aa130221f0",
      "status": "active",
      "dateISO": "2025-10-09T07:41:23.585Z",
      "lotId": "0fd823a7abaa40e6af94c1e4b667ff86",
      "supplierName": "ТОВАРИСТВО З ОБМЕЖЕНОЮ ВІДПОВІДАЛЬНІСТЮ \"ЛІТПОЛ-УКРАЇНА\"",
      "supplierEdrpou": "32134535",
      "supplierScale": "sme",
      "amount": 100000,
      "currency": "UAH"
    }
  ],
  "contracts": [
    {
      "contractID": "UA-2025-09-26-003752-a-c1",
      "status": "active",
      "amount": 100000,
      "currency": "UAH"
    }
  ],
  "documents": [
    {
      "title": "Додаток 1.  Цінова пропозиція.docx",
      "url": "https://public-docs.prozorro.gov.ua/get/c11132697f524553b682daaf8d44d160?Signature=...",
      "type": "biddingDocuments",
      "format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "documentOf": "tender",
      "datePublishedISO": "2025-09-26T08:00:23.595Z"
    },
    {
      "title": "Додаток 2.  Технічні характеристики.docx",
      "url": "https://public-docs.prozorro.gov.ua/get/134a567ffc9349d9ad5a65ca86a1368a?Signature=...",
      "type": "biddingDocuments",
      "format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "documentOf": "tender",
      "datePublishedISO": "2025-09-26T08:00:23.595Z"
    }
  ],
  "input": "filters"
}
```

#### Statuses

| Status | Meaning |
|---|---|
| `active.enquiries` | Clarifications period, bids not accepted yet |
| `active.tendering` | Accepting bids |
| `active.pre-qualification` | Bidders are being checked before the auction |
| `active.auction` | Auction in progress |
| `active.qualification` | The buyer is checking the best bid |
| `active.awarded` | Winner chosen, contract not signed yet |
| `complete` | Contract signed |
| `cancelled` | Cancelled by the buyer |
| `unsuccessful` | No valid bids |

### Limits

- **10,000 results per search.** Prozorro's search serves at most 500 pages of 20 results. To go further, split the search by region, CPV code, status, value range, or dates.
- **About 50 tenders a minute.** prozorro.gov.ua allows 60 requests a minute, and each tender needs one of them to look up its full record. The actor stays under that limit instead of hammering the site, so 1,000 tenders take about 20 minutes.
- **Bids appear late.** Prozorro discloses bids after the bidding period ends, so open tenders show `numberOfBids: 0`.
- **Date filter and direct purchases.** `dateFrom` and `dateTo` filter by the bidding period. Direct purchase reports (`reporting`) have no bidding period, so a date-filtered search leaves them out.
- **One region per search.** Prozorro filters by one region at a time, so the actor runs a search per region and labels each tender with it in `input`.

### How much does it cost?

You pay per tender saved to the dataset: $2.00 per 1,000 tenders. Details don't cost extra.

### Export and integrations

- Download results as JSON, CSV, Excel, XML, HTML, or RSS from the **Output** tab.
- Send them to Google Sheets, Slack, Zapier, Make, and other tools through Apify integrations.
- Schedule runs, for example every morning with `statuses: ["active.tendering"]` and `sortBy: "newest"`, to catch new tenders.
- Start runs and read the results from your own code through the Apify API.

```bash
curl -X POST "https://api.apify.com/v2/acts/<username>~prozorro-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"cpvCodes": ["30210000-4"], "statuses": ["active.tendering"], "maxItems": 50}'
```

### FAQ

#### Is this the official Prozorro API?

The actor reads the same open data that prozorro.gov.ua shows: the site's search for finding tenders and Prozorro's public API for their full records. You don't need a broker account or an API key.

#### Why are some tenders in Ukrainian only?

Buyers write tenders in Ukrainian. Procedures with English publication, such as `aboveThresholdEU`, also carry English titles on Prozorro, but the actor returns the Ukrainian fields.

#### Can I get every tender of one buyer?

Yes. Put the buyer's EDRPOU in `buyerEdrpou` and leave the search queries empty. Buyers with more than 10,000 tenders need the search split by dates or status.

#### Why is the winner empty?

The tender has no active award yet: it's still accepting bids, under review, cancelled, or unsuccessful.

#### Can I scrape contracts and procurement plans?

This actor covers tenders. Each tender's `contracts` list (with **Include details**) gives the signed contracts with amounts and dates.

#### Is it legal to scrape Prozorro?

Prozorro publishes procurement data as open data under Ukrainian law. Records still name contact persons and individual entrepreneurs, so handle personal data according to the GDPR and the laws that apply to you.

### Disclaimer

This actor isn't affiliated with Prozorro or the Ministry of Economy of Ukraine. It's provided as is, without warranty. You're responsible for how you use the data.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search tenders for, in Ukrainian as they appear in tender titles (for example "ноутбук" or "ремонт дороги"). Each query runs as its own search with all the filters below.

## `buyerEdrpou` (type: `array`):

Only tenders announced by these buyers, by their 8-digit EDRPOU code.

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

Only tenders for these CPV (DK 021:2015) codes, for example "30210000-4" for computers.

## `regions` (type: `array`):

Only tenders whose buyer is in these regions. Each region runs as its own search.

## `statuses` (type: `array`):

Only tenders in these statuses.

## `procurementMethodTypes` (type: `array`):

Only tenders run under these procedures.

## `minAmount` (type: `integer`):

Only tenders whose expected value is at least this many hryvnias.

## `maxAmount` (type: `integer`):

Only tenders whose expected value is at most this many hryvnias.

## `dateFrom` (type: `string`):

Only tenders whose bidding period starts on or after this date (YYYY-MM-DD). Direct purchases have no bidding period and drop out of a date-filtered search.

## `dateTo` (type: `string`):

Only tenders whose bidding period starts on or before this date (YYYY-MM-DD).

## `sortBy` (type: `string`):

Order of search results.

## `tenderIds` (type: `array`):

Specific tenders to fetch, by their UA-... ID (for example UA-2026-10-16-013225-a).

## `startUrls` (type: `array`):

Links to tender pages on prozorro.gov.ua, for example https://prozorro.gov.ua/tender/UA-2026-10-16-013225-a.

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

The maximum number of tenders to scrape from each search query and region. Prozorro serves up to 10,000 results per search.

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

Add the full lists of items, lots, bids, awards, contracts, and documents to each tender. Without it you still get the buyer, CPV, value, periods, number of bids, and the winner.

## `proxyCountryCode` (type: `string`):

Two-letter country code (UA, PL, ...) to use Apify residential proxy in that country. "None" uses Apify datacenter proxy.

## Actor input object example

```json
{
  "searchQueries": [
    "ноутбук"
  ],
  "sortBy": "relevance",
  "maxItems": 50,
  "includeDetails": false,
  "proxyCountryCode": "None"
}
```

# Actor output Schema

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

One item per Prozorro tender found by the searches, filters, and tender IDs in the input.

# 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 = {
    "searchQueries": [
        "ноутбук"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("donjuan_mime/prozorro-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 = {
    "searchQueries": ["ноутбук"],
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("donjuan_mime/prozorro-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 '{
  "searchQueries": [
    "ноутбук"
  ],
  "maxItems": 50
}' |
apify call donjuan_mime/prozorro-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,donjuan_mime/prozorro-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/SVLQ8BZeSyCZzHSWN/builds/yssvvXt5b7fwGFDf8/openapi.json
