# Poland Court & Business Gazette API – MSiG Announcements (`enterprising_hamster/polish-company-announcements-msig`) Actor

Daily Monitor Sądowy i Gospodarczy (Polish Court and Business Gazette) notices about companies and other legal entities: bankruptcy, restructuring, liquidation, mergers, transformations, creditor calls, with KRS and court. Natural persons excluded. JSON, CSV, Excel.

- **URL**: https://apify.com/enterprising_hamster/polish-company-announcements-msig.md
- **Developed by:** [Kamil Kaczmarek](https://apify.com/enterprising_hamster) (community)
- **Categories:** Lead generation, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 announcements

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

## Poland MSiG API – Company Bankruptcy & Liquidation Notices

Daily **Monitor Sądowy i Gospodarczy** notices about **legal entities** (companies, foundations, associations, cooperatives and other registered forms): bankruptcy, liquidation, mergers, demergers, transformations, KRS dissolution and creditor calls. Each row has the issue date and number, Poz. position, chapter, kind, entity name, legal form, KRS when present, court and case signature when present, a link to the official PDF, and a short description.

Natural-person notices (consumer bankruptcy, sole traders, surname-and-forename TOC lines) are dropped. Full notice text is off by default because it often names liquidators and shareholders.

Data is read from the official daily PDFs listed at [wyszukiwarka-msig.ms.gov.pl](https://wyszukiwarka-msig.ms.gov.pl/). The actor does not mass-query the Ministry search API.

### Who it is for

#### Lead generation

A buyer who sells services to companies in bankruptcy, liquidation, or a merger gets the entity name, the legal form, the KRS when the header has it, the court, the case signature, and `pdfUrl`. The actor does not return a phone number, an email, an address, or a lead score. A row is a court notice. It is not a qualified lead.

#### Compliance watch

A buyer who monitors a portfolio filters with `krsNumbers` or `announcementKinds`. The kinds for this job are `bankruptcy`, `liquidation`, `merger`, and `creditor_call`. The actor infers `announcementKind` from the table of contents and the opening of the notice. A miss lands in `other`. A demerger is the separate kind `demerger`, and it does not come back as `merger`. Not every sentence about creditors is `creditor_call`. `keywords` matches the entity name, the legal form, the chapter, the subsection, the kind, and the KRS. It does not search the notice body.

### Use with AI agents (MCP)

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=enterprising_hamster/polish-company-announcements-msig"
    }
  }
}
```

- "Liquidation notices for Polish companies from today's MSiG" → `{"lastDays": 1, "announcementKinds": ["liquidation"], "maxItems": 50}`
- "Bankruptcy and restructuring of companies in the last three issues" → `{"lastDays": 3, "announcementKinds": ["bankruptcy", "restructuring"], "maxItems": 200}`
- "Anything for this KRS this week" → `{"lastDays": 7, "krsNumbers": ["0000577818"]}`
- "Merger notices from today's MSiG" → `{"lastDays": 1, "announcementKinds": ["merger"], "maxItems": 50}`
- "Creditor calls from today's MSiG" → `{"lastDays": 1, "announcementKinds": ["creditor_call"], "maxItems": 50}`

### What data can you get

| Field | Meaning |
| --- | --- |
| `id` | `{monitorNumber}-{position}`, for example `215/2026-50873` |
| `monitorDate`, `monitorNumber` | Cover date and issue number |
| `position` | Poz. number in that issue |
| `chapter`, `subsection` | Table-of-contents headings |
| `announcementKind` | `liquidation`, `merger`, `demerger`, `transformation`, `bankruptcy`, `restructuring`, `dissolution`, `creditor_call`, or `other` |
| `entityName`, `legalForm` | Name and detected form (`spółka z o.o.`, `fundacja`, …) |
| `krs` | 10-digit KRS from the notice header, or `null` |
| `court`, `caseSignature` | Registry court and `sygn. akt` when the header has them |
| `pdfUrl` | Official PDF for the whole issue |
| `description` | Subsection title plus entity name from the table of contents. Never the notice body |
| `fullText` | `null` unless `fullText` is true |

Example row (2026-11-02, issue 213/2026):

```json
{
  "id": "213/2026-50354",
  "monitorDate": "2026-11-02",
  "monitorNumber": "213/2026",
  "position": 50354,
  "announcementKind": "liquidation",
  "entityName": "DEA CAPITAL REAL ESTATE POLAND SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ W LIKWIDACJI w Warszawie",
  "legalForm": "spółka z o.o.",
  "krs": "0000786172",
  "court": "SĄD REJONOWY DLA M.ST. WARSZAWY W WARSZAWIE, XII WYDZIAŁ GOSPODARCZY KRAJOWEGO REJESTRU SĄDOWEGO",
  "pdfUrl": "https://wyszukiwarka-msig.ms.gov.pl/api/Monitor/Download?id=9008&fileId=true",
  "fullText": null
}
```

### Input

| Field | Default | Meaning |
| --- | --- | --- |
| `lastDays` | `1` | Issues with cover date on or after today minus N-1 days. Ignored when `dateFrom` or `dateTo` is set |
| `dateFrom`, `dateTo` | none | Inclusive ISO dates (`YYYY-MM-DD`) |
| `announcementKinds` | `[]` | Optional kind filter |
| `keywords` | `[]` | Match on name, legal form, chapter, subsection, kind or KRS. The notice body is not searched |
| `krsNumbers` | `[]` | Optional 6–10 digit KRS list |
| `fullText` | `false` | Store the full notice. GDPR warning in the input schema. Leave false unless you have a lawful basis |
| `maxItems` | `50` | Maximum saved rows |
| `onlyNew`, `stateKey` | `false` | Skip ids already stored for that key |
| `maxRequestsPerSecond` | `1` | Spacing of GetFiles and PDF downloads |

`{}` reads today's issue and saves up to 50 legal-entity rows. A local empty-input run on 2026-11-04 finished in 13 s with 50 rows from issue 215/2026 (227 TOC entries in that PDF).

### Daily alert of new notices

1. Save a task with `onlyNew: true`, `lastDays: 1` and your own `stateKey`.
2. Schedule it (for example `0 7 * * 1-5`).
3. Send the dataset onward with an integration.

```json
{
  "lastDays": 1,
  "onlyNew": true,
  "stateKey": "pl-msig-daily",
  "maxItems": 200,
  "maxRequestsPerSecond": 1
}
```

### Run the public example task

1. Open https://apify.com/enterprising_hamster/polish-company-announcements-msig/examples/daily-poland-liquidations-bankruptcies-alert
2. Choose **Try for free**, or open https://console.apify.com/create-task-from-example/SfcwRvaSQJtQolhbT if you already signed in.
3. Start the copied task. It uses `lastDays` 1, the kinds `bankruptcy`, `restructuring`, and `liquidation`, `maxItems` 200, `onlyNew` true, and `maxRequestsPerSecond` 1. The task already has a state key. Leave that key in place so each notice comes back once.
4. Schedule that task on weekdays if a daily list is the goal. Integrations on the task page send the dataset on.

The separate public example [daily-poland-mergers-creditor-calls-alert](https://apify.com/enterprising_hamster/polish-company-announcements-msig/examples/daily-poland-mergers-creditor-calls-alert) uses kinds `merger` and `creditor_call`, `lastDays` 1, `onlyNew` true, and `maxItems` 200. Copy it from https://console.apify.com/create-task-from-example/lEG0PUc9IBZfeeZrO.

For your own task, paste `examples/mergers.json` or `examples/creditor-calls.json`.

### How long a run takes

Local runs on 2026-11-04, parsing the real PDFs:

| Input | Wall time | TOC rows | Dropped as natural persons | Saved rows |
| --- | --- | ---: | ---: | ---: |
| `{}` (today, `maxItems` 50) | 13 s | 227 | 12 (stop at `maxItems`) | 50 |
| `dateFrom`/`dateTo` 2026-11-02..04, `maxItems` 2000 | 40 s | 753 | 188 | 565 |

Weekday issues in this sample were 72–90 pages. A longer `dateFrom`/`dateTo` window downloads one extra PDF per extra issue.

### Pricing (pay per event)

Each saved announcement costs $0.003.

| Event | Price (USD) | When |
| --- | --- | --- |
| `announcement` | 0.003 | Each saved legal-entity row |

50 announcements cost $0.15. Higher Apify plans pay less: SILVER $0.0027 and GOLD $0.0024 per announcement (same FREE/BRONZE/SILVER/GOLD/PLATINUM/DIAMOND ratios as our Prozorro tender event: $0.003/$0.003/$0.0027/$0.0024/$0.0024/$0.0024). Rows skipped by `onlyNew`, by filters, or as natural persons are not charged. Set a maximum charge per run to cap spending.

### FAQ

**What does one announcement cost?** $0.003 for each saved legal-entity row. Rows dropped by filters, `onlyNew`, or the natural-person check are not charged. 50 saved rows cost $0.15 at that rate.

**How do I start the example task?** Open https://apify.com/enterprising_hamster/polish-company-announcements-msig/examples/daily-poland-liquidations-bankruptcies-alert and start from Try for free. You get a copy with the input already set.

**How do I watch mergers or creditor calls?** Set `announcementKinds` to `merger` or `creditor_call` and use `examples/mergers.json` or `examples/creditor-calls.json` as pasteable inputs. `announcementKind` is inferred from the table of contents and the start of the notice, so some rows land in `other` or in an earlier kind.

**Why are natural persons missing?** Only table-of-contents lines with a legal form are saved. Consumer bankruptcy and sole traders are dropped. Keep `fullText` false unless you have a basis to store names of liquidators and shareholders.

### Limitations

- Two-column body text is reconstructed by a mid-page crop. A rare layout change can mangle `court` or `caseSignature` while TOC name and kind still work.
- Section XV (bulk KRS dump, separate Poz. series) is skipped.
- Kind is inferred from chapter, subsection and wording. Edge cases land in `other`.
- The only-new memory keeps 50,000 ids per `stateKey`.

### Disclaimer

Unofficial tool. Not affiliated with or endorsed by the Polish Ministry of Justice. Always read the source PDF before you act on a notice. MSiG is an official journal. Check the current Ministry terms before commercial reuse. Every row carries `pdfUrl` back to the source PDF.

### Development

```bash
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt -r requirements-dev.txt
.venv/bin/python -m pytest -q
```

PDF layout notes: `docs/source.md`.

# Changelog

This Actor's version history is a separate document: https://apify.com/enterprising_hamster/polish-company-announcements-msig/changelog.md

# Actor input Schema

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

Keep issues whose cover date is on or after today minus N-1 days. Ignored when dateFrom or dateTo is set. Default 1 is today's issue only.

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

Inclusive ISO date (YYYY-MM-DD). When set, lastDays is ignored.

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

Inclusive ISO date (YYYY-MM-DD). When set, lastDays is ignored.

## `announcementKinds` (type: `array`):

Optional. Keep only these kinds. Empty means every legal-entity notice.

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

Matched against the entity name, the legal form, the chapter line, the subsection line, the kind, and KRS. The notice body is not searched.

## `krsNumbers` (type: `array`):

Optional. Keep notices whose header KRS matches (6-10 digits, padded to 10).

## `fullText` (type: `boolean`):

Off by default. When on, fullText is the notice body and can name liquidators, shareholders, and other people. Turn it on only when you have a legal basis to store that text. Notices about natural persons are never returned.

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

Stop pushing once this many legal-entity rows are saved.

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

Minimum spacing between GetFiles and PDF download requests to the Ministry site.

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

Skip ids stored under stateKey in the polish-msig-seen key-value store (50,000 ids per key).

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

Key in the seen store when onlyNew is true. Use a unique name per alert task.

## Actor input object example

```json
{
  "lastDays": 1,
  "announcementKinds": [],
  "keywords": [],
  "krsNumbers": [],
  "fullText": false,
  "maxItems": 50,
  "maxRequestsPerSecond": 1,
  "onlyNew": false
}
```

# Actor output Schema

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

Legal-entity announcement 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 = {
    "lastDays": 1,
    "announcementKinds": [],
    "keywords": [],
    "krsNumbers": [],
    "fullText": false,
    "maxItems": 50,
    "maxRequestsPerSecond": 1,
    "onlyNew": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("enterprising_hamster/polish-company-announcements-msig").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 = {
    "lastDays": 1,
    "announcementKinds": [],
    "keywords": [],
    "krsNumbers": [],
    "fullText": False,
    "maxItems": 50,
    "maxRequestsPerSecond": 1,
    "onlyNew": False,
}

# Run the Actor and wait for it to finish
run = client.actor("enterprising_hamster/polish-company-announcements-msig").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 '{
  "lastDays": 1,
  "announcementKinds": [],
  "keywords": [],
  "krsNumbers": [],
  "fullText": false,
  "maxItems": 50,
  "maxRequestsPerSecond": 1,
  "onlyNew": false
}' |
apify call enterprising_hamster/polish-company-announcements-msig --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,enterprising_hamster/polish-company-announcements-msig"
        }
    }
}
```

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/GEr04YL2A0GozzKy6/builds/TpbXJX3dNu0kzPVhz/openapi.json
