# KRS Corporate Field History (`danielmichalek/krs-corporate-field-history`) Actor

Reconstruct legal-name, legal-form, registered-capital and nominal-share-value changes for Polish S.A. companies from official full KRS extracts. Includes entry dates and source evidence.

- **URL**: https://apify.com/danielmichalek/krs-corporate-field-history.md
- **Developed by:** [Daniel Michałek](https://apify.com/danielmichalek) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$10.00 / 1,000 complete company history reports

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

## KRS Corporate Field History

Reconstruct selected changes to a Polish company's corporate fields from the Ministry of Justice's full KRS extract. Each supported change links the previous and subsequent values to a registry entry number, its recorded date and source pointers.

### Scope

The initial supported company type is **SPÓŁKA AKCYJNA (S.A.)**, identified by its current legal form in register `P`. Other current forms—including sp. z o.o., P.S.A. and partnerships—and register `S` are unsupported. Historical legal-form values may appear in the history of a supported S.A.

Choose any of these four fields:

| Input field | Meaning |
| --- | --- |
| `legalName` | Registered corporate name |
| `legalForm` | Registered legal form |
| `registeredCapital` | Registered share capital, with source currency |
| `shareUnitValue` | Nominal value of one share, with source currency |

The output excludes individuals, officers, owners/shareholders, PESEL, addresses, contact details and raw full extracts. It also excludes share counts, financial statements and company-risk scores.

This is **historical field data**. A returned entry from 2009 remains a historical entry, regardless of when you run the Actor. The recorded entry date is not guaranteed to be the business or legal effective date. A removed field does not establish that the company was dissolved. Nominal share value is not market price; a decrease does not by itself imply a decrease in registered capital or financial weakness.

### Input

Supply explicit KRS numbers as ten-digit strings, including leading zeroes. This three-company example requests all four fields and the available source history:

```json
{
  "krsNumbers": ["0000028860", "0000026438", "0000009831"],
  "fields": ["legalName", "legalForm", "registeredCapital", "shareUnitValue"]
}
```

These numbers identify ORLEN, PKO BP and PZU. They are examples of existing companies, not a list of newly changed companies.

To restrict the historical period, add `entryDateFrom` and/or `entryDateTo` as `YYYY-MM-DD` strings, for example `"entryDateFrom": "2023-01-01"` and `"entryDateTo": "2023-12-31"`. These filter **recorded registry-entry dates**, not the fetch time or a promised effective date. Omit both dates for the available source history. The start date must not follow the end date.

Input accepts 1–10 KRS entries. Repeated numbers are deduplicated and do not create an extra company charge. The optional `fields` array must contain at least one supported field; omission selects all four. There is no company-name search, arbitrary source URL, API-key input, PDF retrieval or automatic monitoring schedule.

### API usage

These are instructions for your own run, not evidence of a completed run. Use `curl` and `jq`, an account with access to this Actor, and your own token in the `APIFY_TOKEN` environment variable. The [official run API](https://docs.apify.com/api/v2/act-runs-post) accepts a timeout in seconds, memory in MB and `maxTotalChargeUsd` as a PPE charge limit. This example requests 90 seconds, 512 MB and at most USD 0.03 in PPE charges; check the active Pricing tab first.

Start asynchronously with the three example companies. The response contains the run ID, not the reports. **If the POST times out or loses its connection, inspect your account’s recent runs and any returned run ID before repeating it.** A new POST may start another billable run.

```bash
: "${APIFY_TOKEN:?Set APIFY_TOKEN in your environment}"
curl --fail --silent --show-error --max-time 30 --request POST \
  'https://api.apify.com/v2/acts/danielmichalek~krs-corporate-field-history/runs?timeout=90&memory=512&maxTotalChargeUsd=0.03' \
  --header "Authorization: Bearer ${APIFY_TOKEN}" \
  --header 'Content-Type: application/json' \
  --data '{"krsNumbers":["0000028860","0000026438","0000009831"],"fields":["legalName","legalForm","registeredCapital","shareUnitValue"]}' \
  --output krs-run-start.json || exit 1
KRS_RUN_ID=$(jq -er '.data.id' krs-run-start.json) || exit 1
```

Check `GET /v2/actor-runs/RUN_ID` until it reaches a terminal status. This loop makes at most 60 requests, waiting three seconds between continuing statuses. A failed request, exhausted polling or a failed/aborted run does not authorize a fresh POST: inspect the existing run first.

```bash
KRS_RUN_STATUS=UNKNOWN
for KRS_POLL_ATTEMPT in $(seq 1 60); do
  curl --fail --silent --show-error --max-time 30 \
    "https://api.apify.com/v2/actor-runs/${KRS_RUN_ID}" \
    --header "Authorization: Bearer ${APIFY_TOKEN}" \
    --output krs-run-status.json || exit 1
  KRS_RUN_STATUS=$(jq -er '.data.status' krs-run-status.json) || exit 1
  case "$KRS_RUN_STATUS" in
    SUCCEEDED|FAILED|TIMED-OUT|ABORTED|ERROR) break ;;
    *) sleep 3 ;;
  esac
done
```

Download only after `SUCCEEDED`. Use `defaultDatasetId` for the company-report JSON and `defaultKeyValueStoreId` for `OUTPUT` and the stored flat CSV. A successful run can still have partial company coverage; inspect `krs-output.json` and each report’s completeness before using the CSV.

```bash
test "$KRS_RUN_STATUS" = SUCCEEDED || exit 1
KRS_DATASET_ID=$(jq -er '.data.defaultDatasetId' krs-run-status.json) || exit 1
KRS_STORE_ID=$(jq -er '.data.defaultKeyValueStoreId' krs-run-status.json) || exit 1
curl --fail --silent --show-error --max-time 30 \
  "https://api.apify.com/v2/key-value-stores/${KRS_STORE_ID}/records/OUTPUT" \
  --header "Authorization: Bearer ${APIFY_TOKEN}" --output krs-output.json || exit 1
curl --fail --silent --show-error --max-time 30 \
  "https://api.apify.com/v2/datasets/${KRS_DATASET_ID}/items?format=json" \
  --header "Authorization: Bearer ${APIFY_TOKEN}" --output krs-reports.json || exit 1
curl --fail --silent --show-error --max-time 30 \
  "https://api.apify.com/v2/key-value-stores/${KRS_STORE_ID}/records/SUMMARY_CSV" \
  --header "Authorization: Bearer ${APIFY_TOKEN}" --output krs-changes.csv || exit 1
```

### How a change is established

For a single-value field, a change requires exactly one previous value ending and exactly one subsequent value starting at the same registry entry. The reconstruction uses `nrWpisuWykr` and `nrWpisuWprow`, then joins the entry number to a unique dated header entry. Array position is not treated as chronology.

Names and forms receive conservative normalization. Monetary values retain decimal-string precision and their original currency; currencies are not converted. Before/after values are normalized for reporting; exact source pointers locate the original source records. A repeated insertion of the same material value is not a change, and the initial recorded value is not emitted as a transition.

Gaps, overlaps, conflicting values, missing or duplicate entry bindings, unknown amount/date formats and unsupported forms produce diagnostics. An incomplete or truncated report must not be interpreted as a complete history. “Complete” applies to the supported selected fields and the requested date scope in the available full extract.

### Outputs

| Output | Contents |
| --- | --- |
| Default dataset | One bounded company report, including completeness, selected scope, `changes[]`, safe diagnostics and source evidence |
| `RESULTS` | Delivered company reports as JSON |
| `SUMMARY_CSV` | One flat row per material field change |
| `COMPANY_SUMMARY` | Short per-company status, change count and diagnostic codes |
| `OUTPUT` | Run coverage, stop reason and billing summary |

A change carries its field, before/after values, registry entry number, recorded entry date and exact source pointers. Source evidence identifies the official URL and hash, `fetchedAt`, and the source strings `generatedAtRaw` and `stateDateRaw`. Raw source dates are not assigned an inferred timezone or used as event dates. These are **derived and normalized reports, not official extracts**.

The flat CSV columns are `krs`, `field`, `entryNumber`, `entryDate`, `beforeValue`, `beforeCurrency`, `afterValue`, `afterCurrency`, `sourceUrl`, `beforePointer`, `afterPointer` and `entryPointer`. Every cell is quoted and escaped. KRS numbers and monetary value cells also receive a leading apostrophe (`'`), such as `'0000028860` or `'1000000000.00`, to keep them textual in spreadsheet workflows. Other text that begins with a spreadsheet-formula character receives the same protection. Some CSV readers display this apostrophe literally. JSON has no added apostrophe and is the preferred source for typed programmatic processing; do not convert KRS identifiers or decimal monetary strings through floating-point numbers.

Always inspect `OUTPUT` and the company summary before using the event CSV. An empty event CSV alone does not distinguish a complete report with no changes from an incomplete or unsupported report.

### Actual local example

A saved-source engine execution on 26 October 2026 returned complete reports with four material events for ORLEN, two for PKO BP and two for PZU, using all four fields and no date filter. This is local evidence, not a cloud run or a payment confirmation.

The following event is copied from the ORLEN report (`krs: "0000028860"`); it is one of that report’s four events, not the entire company report:

```json
{
  "field": "legalName",
  "before": "POLSKI KONCERN NAFTOWY ORLEN SPÓŁKA AKCYJNA",
  "after": "ORLEN SPÓŁKA AKCYJNA",
  "entryNumber": 151,
  "entryDate": "2023-07-03",
  "sourcePointers": {
    "before": "/odpis/dane/dzial1/danePodmiotu/nazwa/0",
    "after": "/odpis/dane/dzial1/danePodmiotu/nazwa/1",
    "entry": "/odpis/naglowekP/wpis/150"
  }
}
```

The event is dated 3 July 2023 even though the source was fetched in October 2026. Its source pointers address the original full extract. The locally recorded `completed: true` and `billable: true` indicate report completion and eligibility under the per-company billing contract; they do not establish that a cloud charge occurred.

### Billing

In pay-per-event mode, one `company-ledger-returned` event costs **USD 0.01 per complete supported company report**. Check the Actor’s Pricing tab for the active configuration before running. This includes a successfully completed date window containing **zero material changes**. Repeating the same request can deliver and bill another complete report even if its historical data is unchanged.

Invalid, not-found, unsupported, incomplete, timed-out and failed reports are uncharged; duplicate input numbers do not create another charge. Under this per-company PPE configuration, platform usage is included and there are no positive startup, default-dataset or auxiliary event fees.

A zero effective charge budget stops source work. The affordable company prefix is selected before fetching; a failed uncharged company does not automatically expand that prefix. Inspect requested and delivered coverage instead of assuming all supplied KRS numbers were processed. Ambiguous delivery or charge confirmation blocks automatic replay; inspect the existing run before starting a separate one.

### Limits and access

The implementation accepts at most 10 companies and uses sequential requests with a shared 60-second deadline for source work. Dataset, storage and SDK delivery calls also depend on the configured platform run timeout; 60 seconds is not a guaranteed total wall-clock duration. Source limits are 4 MiB per response, 32 MiB total received and 15 HTTP attempts including retries. Each company report is limited to 100 material changes and 512 KiB. Reaching a bound can make a company incomplete and uncharged; these limits are not throughput guarantees.

HTTP 429 and `Retry-After` are handled within the remaining time budget. HTTP 401/403 stop access without bypassing restrictions. Cancellation stops further source work and new paid deliveries; an already-started write/charge call cannot be rolled back automatically.

The fixed source is the Ministry of Justice / PRS / KRS full-extract API:

```text
https://api-krs.ms.gov.pl/api/krs/OdpisPelny/{krs}?rejestr=P&format=json
```

The [official PRS documentation](https://prs.ms.gov.pl/krs/openApi) describes public access to current and full extracts, including deleted information. Its statutory reuse basis references the KRS Act and Poland's Open Data and Reuse Act. This is **not a claimed Creative Commons licence or blanket permission to reuse personal sections of KRS records**. Source and transformation notices are retained, and the customer output is restricted to the four corporate fields above.

# Actor input Schema

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

One to ten exact ten-digit strings with leading zeroes. Repeated numbers are processed once and do not incur a duplicate report charge. The example companies demonstrate historical changes, not recent activity.

## `fields` (type: `array`):

Explicit corporate field allowlist. Nominal share value is not market price. Initial values and metadata-only reinsertion are not material changes.

## `entryDateFrom` (type: `string`):

Optional inclusive YYYY-MM-DD lower bound on the recorded registry entry date. This date is not guaranteed to be the business or legal effective date. Omit for available history.

## `entryDateTo` (type: `string`):

Optional inclusive YYYY-MM-DD upper bound on the recorded registry entry date; must be on or after entryDateFrom. Omit for available history.

## Actor input object example

```json
{
  "krsNumbers": [
    "0000028860",
    "0000026438",
    "0000009831"
  ],
  "fields": [
    "legalName",
    "legalForm",
    "registeredCapital",
    "shareUnitValue"
  ]
}
```

# Actor output Schema

## `companies` (type: `string`):

No description

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

No description

## `companySummary` (type: `string`):

No description

## `csv` (type: `string`):

No description

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

No description

# 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 = {
    "krsNumbers": [
        "0000028860",
        "0000026438",
        "0000009831"
    ],
    "fields": [
        "legalName",
        "legalForm",
        "registeredCapital",
        "shareUnitValue"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("danielmichalek/krs-corporate-field-history").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 = {
    "krsNumbers": [
        "0000028860",
        "0000026438",
        "0000009831",
    ],
    "fields": [
        "legalName",
        "legalForm",
        "registeredCapital",
        "shareUnitValue",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("danielmichalek/krs-corporate-field-history").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 '{
  "krsNumbers": [
    "0000028860",
    "0000026438",
    "0000009831"
  ],
  "fields": [
    "legalName",
    "legalForm",
    "registeredCapital",
    "shareUnitValue"
  ]
}' |
apify call danielmichalek/krs-corporate-field-history --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,danielmichalek/krs-corporate-field-history"
        }
    }
}
```

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/jPIbamCB6YC2yYE7g/builds/q6M1fFG1VJpWPkfn9/openapi.json
