# Poland UOKiK Decisions Scraper (`regdata/uokik-decisions-scraper`) Actor

Search and extract decisions of Poland's competition and consumer protection authority - merger clearances, dominant position abuse, collective consumer interests, fuel quality and prohibited clauses, with named parties, fines and appeal status.

- **URL**: https://apify.com/regdata/uokik-decisions-scraper.md
- **Developed by:** [getregdata](https://apify.com/regdata) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 decision records

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Poland UOKiK Decisions Scraper

Extract decisions of the President of Poland's Office of Competition and Consumer Protection
(Urząd Ochrony Konkurencji i Konsumentów) from the official register at
[decyzje.uokik.gov.pl](https://decyzje.uokik.gov.pl).

About **22,000 decisions**, from 2000 to today, covering merger control, abuse of a dominant
position, agreements restricting competition, collective consumer interests, fuel quality,
general product safety, contractual advantage and payment gridlocks.

Every decision comes back with the **named party**, the decision number and date, the case
signature, the practice type, whether a **fine** was imposed, whether the decision was
**appealed**, the party's **PKD industry**, and the **voivodeship**.

No API key. No login. No captcha.

***

### What you get

```json
{
  "decisionNumber": "DOZIK-2/2026",
  "dateOfDecision": "2026-01-30",
  "party": "Orange Polska Spółka Akcyjna z siedzibą w Warszawie",
  "practiceType": "Klauzule niedozwolone",
  "caseSignature": "DOZIK-3.611.1.2022.AG",
  "fineImposed": true,
  "appealed": true,
  "industryCode": "61.10",
  "industryName": "DZIAŁALNOŚĆ W ZAKRESIE TELEKOMUNIKACJI PRZEWODOWEJ",
  "region": "Mazowieckie",
  "url": "https://decyzje.uokik.gov.pl/bp/dec_prez.nsf/0/E6F57FA89230CD9BC1258D9600412C6D?editDocument&act=Decyzja",
  "unid": "E6F57FA89230CD9BC1258D9600412C6D",
  "detailsFetched": true,
  "incompleteFields": [],
  "scrapedAt": "2026-08-29T12:18:24.827Z"
}
```

`fineImposed` is a **flag, not an amount**. The register records that a fine was imposed and
never publishes how much - so this Actor does not either. Anything presenting a UOKiK fine
figure got it from somewhere else.

***

### Use it for

- **Counterparty and KYC screening** - has this company been sanctioned by the competition
  authority, and did it appeal?
- **Merger tracking** - every clearance decision, by industry sector or by year.
- **Competition and consumer-law research** - a full, structured copy of a register that only
  offers a paginated web form.
- **Compliance monitoring** - watch one company, one sector or one practice type over time.

***

### Input

Leave everything blank to walk the whole register.

| Field | What it does |
|---|---|
| **Company or person** | Party to the proceedings, e.g. `Orange`. Whole-word match, case-insensitive. |
| **Type of practice** | One of the register's 11 categories - merger control, dominant position, consumer interests, fuel quality and the rest. |
| **Decision number** | e.g. `DKK-171/2024`. |
| **Case signature** | e.g. `DKK-2.430`. Matches a prefix too. |
| **Industry (PKD)** | Matches the whole PKD path - see the note below. |
| **Voivodeship** | One of the 16 Polish regions. A decision can list several. |
| **Fine imposed** / **Appealed** | Any / yes / no. |
| **Decided on or after / before** | ISO dates, `YYYY-MM-DD`. |
| **Full-text term** | Free text across the whole document index. |
| **Maximum decisions** | Default 100. `0` means every match. |
| **Fetch full decision details** | On by default. Off returns only what the result list shows. |
| **Include records that identify nothing** | Off by default. See below. |

#### Two things worth knowing before you filter

**Polish diacritics matter.** The register's search is literal. `Jakość paliw` finds 1,403
decisions; `Jakosc paliw` finds none.

**The industry filter matches the PKD *path*, not the label you see.** The register stores
`SEKCJA F BUDOWNICTWO … WYKONYWANIE INSTALACJI ELEKTRYCZNYCH` but each decision page displays
only the last part. So `SEKCJA K` selects the entire financial sector, `TELEKOMUNIKACJA`
selects one class - and `BUDOWNICTWO` correctly returns electrical-installation firms, because
that class sits under Section F. It looks like a mismatch and is not.

***

### Completeness

A scraper of a paginated register can fail in one direction only: it returns a short list that
looks whole. Three things make that visible here.

**The run summary.** Every run writes a `SUMMARY` record saying how many rows were listed, how
many duplicates and unidentified records were dropped, and - the field that matters -
`completeForThisQuery`. It is `false` whenever your **Maximum decisions** cut the list, and
`decisionsAvailable` then tells you how many the search actually matched.

**A failed request fails the run.** The walk ends when the register returns a short page. If a
request keeps failing after its retries, the run errors out rather than pushing a partial
dataset that would look complete.

**Duplicates and blanks are counted, not hidden.** The register publishes a few decisions twice
under different document IDs, and holds six documents with no number, date or party at all.
Both are excluded by default; both appear in the summary. Set **Include records that identify
nothing** if you want the six blanks in your dataset.

There is also a quirk the register itself will tell you about if you go looking: any single
search response is capped at 6,000 rows, and its own counter then reads *"Znaleziono ponad
6000"* - "more than 6000". That is a limit on one response, not on what a search can reach, and
this Actor pages straight through it.

***

### Notes

- Data is public information published by UOKiK under Polish law.
- The Actor reads the register's search view directly over HTTP - no browser, no proxy.
- Decision text itself is not included; the `url` field links to the official page.
- Field values (party names, practice types, industries, regions) are in Polish, as published.

***

### Related Actors

- **Poland KRS Company Search** - company registry records
- **Poland KRZ Debtor Register** - insolvency and restructuring proceedings
- **Poland MSiG Court Gazette** - official court and economic announcements
- **Poland eKRS Financial Statements** - filed financial statements

# Actor input Schema

## `participant` (type: `string`):

Name of a party to the proceedings, e.g. "Orange". Matches whole words in the party field, case-insensitive. Polish diacritics matter - the register's search is literal.

## `practiceType` (type: `string`):

The category of proceedings. Roughly: merger control 5,800 decisions, product-safety conformity 4,000, collective consumer interests 4,000, dominant position 1,900.

## `decisionNumber` (type: `string`):

The decision's own number, e.g. "DKK-171/2024".

## `caseSignature` (type: `string`):

The case file signature, e.g. "DKK-2.430". Matches a prefix as well as a whole signature.

## `industry` (type: `string`):

Matches the whole PKD path, so "SEKCJA K" selects the entire financial sector while "TELEKOMUNIKACJA" selects one class. Because the register stores the path but each decision page shows only the leaf class, a match can look unrelated and still be correct - "BUDOWNICTWO" returns electrical-installation firms, which sit under Section F.

## `region` (type: `string`):

Region the decision applies to. A decision can list several.

## `fineImposed` (type: `string`):

Whether the decision imposed a fine. The register records only THAT a fine was imposed - it never publishes the amount.

## `appealed` (type: `string`):

Whether the decision was appealed.

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

ISO date, YYYY-MM-DD. Note that six records in the register carry no decision date at all and are excluded by any date filter.

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

ISO date, YYYY-MM-DD.

## `fullText` (type: `string`):

Free text searched across the whole document index. Broader than it looks - it matches text the decision page does not display, so use the specific fields above when you can.

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

Stop after this many. Set 0 for every match - the whole register is about 22,000 decisions.

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

Open each decision to read its case signature, fine flag, appeal status, industry and region. Off returns only what the result list shows: number, date, party and practice type.

## `includeIncompleteRecords` (type: `boolean`):

The register holds six documents with no number, date or party. They are skipped by default and always counted in the run summary.

## `proxyConfiguration` (type: `object`):

The register does not accept connections from datacenter IP ranges, so runs on the platform need a residential proxy. Defaults to Apify Proxy residential, Poland - which is also by far the fastest route to this register.

## Actor input object example

```json
{
  "practiceType": "",
  "region": "",
  "fineImposed": "",
  "appealed": "",
  "maxItems": 100,
  "includeDetails": true,
  "includeIncompleteRecords": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "PL"
  }
}
```

# Actor output Schema

## `decisions` (type: `string`):

Decision number, date, party, practice type, case signature, fine and appeal flags, PKD industry, region and the source URL.

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

What the run covered: rows listed, duplicates and unidentified records dropped, and whether the dataset is every match for the search or was cut short by your limit.

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "PL"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("regdata/uokik-decisions-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 = { "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "PL",
    } }

# Run the Actor and wait for it to finish
run = client.actor("regdata/uokik-decisions-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 '{
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "PL"
  }
}' |
apify call regdata/uokik-decisions-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,regdata/uokik-decisions-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/CEp4Ol7kcYxrpoaan/builds/6DrysSNVpjTKUjL5V/openapi.json
