# Polish Company Data & KYB: KRS/NIP/REGON + VAT & Bankruptcy (`datacraft-studio/polish-company-kyb`) Actor

Poland company data for KYB and KYC. Look up a firm by KRS, NIP or REGON: official KRS extract, Biała lista VAT white list status and IBAN check, PKD, capital, board, bankruptcy and liquidation.

- **URL**: https://apify.com/datacraft-studio/polish-company-kyb.md
- **Developed by:** [Yahya Nouali](https://apify.com/datacraft-studio) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 company enricheds

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

## Polish Company Data & KYB

Look up a Polish company by **KRS**, **NIP**, or **REGON** and get a flat record for KYB, KYC, and lead generation: legal name, address, legal form, share capital, PKD codes, board and proxies, **Biała lista VAT** (VAT white list) status, bank-account checks, and a prominent bankruptcy / liquidation / restructuring flag.

The actor reads official, keyless registers:

- Krajowy Rejestr Sądowy open API (`api-krs.ms.gov.pl`) — current extract, and the full extract when you ask for insolvency history
- Ministry of Finance VAT white list (`wykazpodatnikowvat.mf.gov.pl`, legacy host `wl-api.mf.gov.pl` until 1 December 2026)

An optional GUS REGON (BIR1) lookup runs only when you pass your own user key. That is how sole traders (JDG), who are not in KRS, can still be resolved when the white list is not enough.

Invalid identifiers and unknown companies are returned as rows and are **not charged**.

### Why this is useful

- Onboard a Polish counterparty and see, in one row, whether the register shows bankruptcy, liquidation, or restructuring.
- Check that an invoice account is on the VAT white list before a payment. Polish tax rules (Tax Ordinance art. 117ba) attach consequences to paying more than 15,000 PLN to an account that is not on the list. Keep the `vatRequestId` from the Ministry; this actor is not the official certificate.
- Enrich a lead list with legal name, address, PKD, and capital.
- Monitor a portfolio. The first run stores a baseline and is not charged. Later runs return only real changes in status, address, name, board, PKD, VAT status, or insolvency entries.

### Input

| Field | Default | Meaning |
| --- | --- | --- |
| `companies` | — | Objects `{ id, type?, checkIbans? }` or plain strings. `type` is `auto`, `nip`, `regon`, or `krs`. |
| `identifierList` | — | Extra ids separated by newlines, commas, or spaces. |
| `includeBoard` | `true` | Management body, supervisory board, and proxies. The public KRS API masks personal names (for example `D**** B****`), so full names are not provided. PESEL is never output. |
| `includeInsolvencyHistory` | `false` | Also fetch `OdpisPelny` (ended proceedings). Extra charge in enrich mode when the extract is retrieved. |
| `mode` | `enrich` | `monitor` stores snapshots in a named key-value store and emits changes only. |
| `monitorStoreName` | `polish-company-monitor` | Reuse this name so the next run sees the baseline. |
| `regonApiKey` | empty secret | Your GUS BIR1 key. Never written to the dataset. |
| `maxCompanies` | `300` | The run fails instead of truncating. Maximum 3000. |

Detection:

- 9 digits, or 14 digits: REGON, checksum required. A 14-digit value that is a 9-digit REGON plus `00000` (how KRS stores it) is accepted as that REGON-9.
- 10 digits with a valid NIP checksum: NIP, unless `type` is `krs`.
- 10 digits that fail the NIP checksum and start with `0`: KRS. A KRS number is 10 digits with leading zeros.
- 10 digits with no leading zero that fail the NIP checksum: invalid, unless `type` is `krs`. These are not looked up, so they are not returned as `not_found`.
- 1–8 digit numbers: KRS, zero-padded to 10.
- Prefixes `NIP`, `REGON`, and `KRS` are accepted.

```json
{
  "companies": [
    { "id": "7740001454", "checkIbans": ["PL61109010140000071219812874"] },
    { "id": "KRS 28860" },
    { "id": "610188201", "type": "regon" }
  ],
  "includeBoard": true,
  "includeInsolvencyHistory": false,
  "mode": "enrich"
}
```

`7740001454` is the public NIP of ORLEN S.A., a useful connectivity check. It is not an endorsement.

### Output

One JSON object per company, flat enough for CSV. Nested lists are JSON strings (`insolvencyEntriesJson`).

Important fields:

- `found`, `error`, `errorMessage` — `invalid_identifier`, `not_found`, `vat_quota_exceeded`, `source_unavailable`
- `insolvencyFlag` — `true` or `false` when a KRS extract was read, `null` when insolvency was not checked (for example a sole trader found only on the white list)
- `insolvencyStatus` — `none`, `bankruptcy`, `liquidation`, `restructuring`, `multiple`, `unknown`
- `vatStatus` — `active`, `exempt`, `not_registered`, `removed`, `unknown`, `unavailable`
- `status` — `active`, `in_bankruptcy`, `in_liquidation`, `in_restructuring`, `suspended`, `struck_off`, `unknown`
- `name`, `legalForm`, `nip`, `regon`, `regon14`, `krs`
- address parts, `shareCapitalAmount`, `pkdMainCode`, `pkdCodes`
- `boardMembers`, `supervisoryBoard`, `proxies` as `Name (role)` joined with `; `. The public KRS API returns personal names already masked, for example `D**** B****`. Full names are not provided, and this actor does not try to recover them.
- `vatAccountNumbers`, `ibanChecks` as `nrb:assigned`, `not_assigned`, `local_match`, `local_miss`, `invalid`, or `unavailable`
- `sources`, `sourceKrsUrl`, `sourceVatUrl`, `vatRequestId`
- `chargedEvents`, `partial`, `warnings`

`local_match` / `local_miss` means the official account-check quota was spent and the actor compared the number with the account list already returned by search. That is not the Ministry's TAK/NIE answer, and it can miss a virtual account. `unavailable` means there was nothing to compare.

Illustrative enrich row. Board names from the public KRS API look like `D**** B****`; the other fields show the shape, not a live extract:

```json
{
  "found": true,
  "insolvencyFlag": false,
  "insolvencyStatus": "none",
  "vatStatus": "active",
  "status": "active",
  "name": "ORLEN SPÓŁKA AKCYJNA",
  "legalForm": "SPÓŁKA AKCYJNA",
  "nip": "7740001454",
  "regon": "610188201",
  "krs": "0000028860",
  "address": "CHEMIKÓW 7, 09-411 PŁOCK, POLSKA",
  "shareCapitalAmount": 1451177561.25,
  "shareCapitalCurrency": "PLN",
  "pkdMainCode": "19.20.Z",
  "pkdMainDescription": "WYTWARZANIE I PRZETWARZANIE PRODUKTÓW RAFINACJI ROPY NAFTOWEJ",
  "boardMembers": "D**** B**** (PREZES ZARZĄDU)",
  "vatStatusRaw": "Czynny",
  "vatAccountCount": 236,
  "ibanChecks": "61109010140000071219812874:assigned",
  "sources": "krs; vat_whitelist",
  "chargedEvents": "company-enriched",
  "mode": "enrich"
}
```

Monitor mode writes a short baseline on the first run (`changeType: baseline`, `chargedEvents` empty). Later runs omit companies that did not change. A change row has `changeType: changed`, `changedFields`, `previousJson`, and `currentJson`.

### Pricing

Pay per event. Figures are the Store prices to configure; see [PUBLISHING.md](PUBLISHING.md).

| Event | Price | When |
| --- | --- | --- |
| `company-enriched` | $0.005 | Enrich mode, and a registry record was found. Primary event. |
| `insolvency-history` | $0.002 | Enrich mode, and the full KRS extract was retrieved. |
| `change-detected` | $0.015 | Monitor mode, and a watched field changed. |

Not found, invalid, the monitor baseline, and unchanged monitor checks are free. Disable the synthetic per-dataset-item charge so those free rows stay free.

### How to run

Node.js 20 or newer.

```bash
npm install
npm test
npm run build
mkdir -p storage/key_value_stores/default
cp examples/input.json storage/key_value_stores/default/INPUT.json
npm start
```

Results land in `storage/datasets/default`. Outside Apify, `billingNote` is `not_billed_outside_apify` and nothing is billed.

Live check against the public registers (uses one VAT search and one KRS read):

```bash
npm run smoke
```

Push to Apify from this directory, or from the tarball produced by `npm run package`:

```bash
npm run package
tar -xzf polish-company-kyb-actor.tar.gz
npm install
apify push
```

The image is `apify/actor-node:20`. No Apify username is baked into the project. In the Store publication form set categories to Lead generation (`LEAD_GENERATION`) and Business (`BUSINESS`). The actor manifest schema has no `categories` field, so they are recorded in [PUBLISHING.md](PUBLISHING.md) instead of `.actor/actor.json`.

### Use cases

- KYB / KYC onboarding of a Polish company before a contract or a payment.
- Accounts-payable white-list checks for a batch of supplier NIPs and IBANs.
- Lead enrichment: PKD, capital, address, and the masked names of people who represent the company.
- Portfolio monitoring for new insolvency entries, address changes, or a VAT status flip.
- Gap-fill for a sole trader when you already hold a GUS REGON key.

### Integrations: Make, Zapier, n8n

You can call this Actor from no-code tools through Apify's official integrations. Use its Actor ID `SXToneTLvcjlKKMPk`, and connect each tool with OAuth or your Apify API token. Never put the token in the Actor input.

- **Make**: in the Apify app, add **Run an Actor** and set *Run synchronously* to Yes. Then add **Get Dataset Items** with the run's default dataset ID, and map the rows to Google Sheets, a CRM or Slack. For long runs, use the **Watch Actor Runs** trigger instead.
- **Zapier**: the Apify app has the **Run Actor** action. A synchronous run has a 30-second hard timeout, so for larger lists start the run and use the **Finished Actor Run** trigger with **Fetch Dataset Items**.
- **n8n**: install the official node `@apify/n8n-nodes-apify`. It is a verified community node on n8n Cloud; on self-hosted n8n, add it under Settings > Community Nodes. Use **Run an Actor and Get Dataset**, or the Apify trigger for finished runs.

Example input:

```json
{"mode": "enrich", "companies": [{"id": "7740001454"}], "includeBoard": true}
```

#### Scheduled monitor to Slack or Sheets

1. Save a monitor input as an Actor task and keep the same store name on every run:

```json
{
  "mode": "monitor",
  "companies": [
    {
      "id": "7740001454"
    }
  ],
  "monitorStoreName": "polish-company-monitor"
}
```

2. In Apify Console > **Schedules**, run the task on a cron such as `0 7 * * 1` (every Monday at 07:00), with your timezone selected.
3. On the task's **Integrations** tab, add Slack or an HTTP webhook on *Run succeeded*. You can also use Make **Watch Actor Runs**, Zapier **Finished Actor Run** or the n8n Apify trigger.
4. Fetch the dataset items and keep only the change rows: `changeType` is `"changed"`. The first run only stores the baseline and is free.

#### HTTP API

This call runs the Actor and returns the dataset rows in one request. Synchronous runs time out after 300 seconds, so use `/runs` for big lists.

```bash
curl -X POST "https://api.apify.com/v2/acts/SXToneTLvcjlKKMPk/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"mode": "enrich", "companies": [{"id": "7740001454"}], "includeBoard": true}'
```

### FAQ

#### Where does the data come from?

KRS Open API, Ministry of Justice, no key: `GET /api/krs/OdpisAktualny/{krs}` and `OdpisPelny/{krs}` with `rejestr=P` (entrepreneurs) or `S` (associations, foundations, and the other entities in that register) and `format=json`. The API does not search by NIP, REGON, or name. This actor learns the KRS number from the VAT white list or, if you supply a key, from BIR1.

VAT white list, Ministry of Finance / KAS, no key. Since 15 October 2026 the production host is `https://wykazpodatnikowvat.mf.gov.pl/api`. `https://wl-api.mf.gov.pl` keeps working until 1 December 2026; this actor tries the new host first and falls back to the legacy host. Search accepts up to 30 NIPs or REGONs per call. The `check` method answers TAK or NIE for one NIP plus account. WL2 (`/api2/status/nip/{nip}`) returns only the VAT status and is used when the search quota is spent.

REGON, GUS BIR1 SOAP, only with your key, and only when KRS did not already provide the name, REGON, or PKD.

#### What are the reuse terms?

Checked against the publishers' notices as of 24 October 2026. This actor does not grant a licence of its own. You get what the publisher gives, and you have to attribute them.

**KRS.** The open API was announced by the Ministry of Justice on 8 March 2022 under the Act of 11 August 2021 on open data and reuse of public sector information. Article 4b of the KRS Act says registry data are made available for reuse under that act, including via API. The Ministry has not published a separate Creative Commons deed for the API. Reuse is statutory and free of charge for the keyless Open API. Attribute *Ministerstwo Sprawiedliwości — Krajowy Rejestr Sądowy*. The published scope is the current and full extract issued by Centralna Informacja KRS, with the Ministry's own GDPR limits already applied. A wider "Full API" that needs a ministerial decision is a different service; this actor does not call it.

**VAT white list.** The list is kept under article 96b of the VAT Act. The Ministry's API notice (gov.pl, Krajowa Administracja Skarbowa) sets operational limits and does not attach a Creative Commons licence. The Ministry's general reuse page says public-sector information is provided for reuse free of charge, that the Ministry is not liable for what a reuser does with it, and that the Ministry may set objective, proportionate, non-discriminatory conditions. Attribute *Ministerstwo Finansów — Wykaz podatników VAT*. `vatRequestId` is the Ministry's confirmation of that query.

**REGON / BIR1.** The register is public under articles 42–45a of the Act of 29 June 1995 on public statistics. Article 45 lists what third parties may receive (name, address, NIP, legal form, activity including the main PKD, dates, the registry identifier, local units). Phone, fax, email, and website of a natural person in CEIDG are not disclosed to third parties. BIR1 is free but requires a user key and acceptance of the GUS regulamin for commercial users: no flooding, no extra accounts to dodge limits, no scanning of sequential identifiers. Published guidance is about 3 requests per second and 120–150 per minute. You remain the BIR1 customer. Attribute *Główny Urząd Statystyczny — rejestr REGON*.

#### What about GDPR and board members?

The public KRS Open API masks board, supervisory-board, and proxy names. A given name and surname come back like `D**** B****`, not as a full name, and this actor returns that masked string as published. It does not reconstruct a name. PESEL, when a source field is present, is also masked by the Ministry (values such as `5**********`); this actor drops PESEL anyway, including PESEL on the VAT white list. These fields are public registry data with the Ministry's own limits already applied.

You are an independent controller for your own purpose (KYB, lead generation, monitoring). The lawful basis is yours to decide. Do not use this actor to download the whole register: it only accepts identifiers you already have. Sole traders are natural persons; treat them with extra care. This output is not legal advice.

#### What happens when the VAT quota runs out?

The Ministry allows 100 search requests per day from an IP address, each for up to 30 entities, 5,000 account checks per day, and 50,000 WL2 status calls per day. The counter resets at midnight Europe/Warsaw. This actor batches searches, caches repeats inside the run, and stores the day's usage in the key-value store `polish-company-vat-quota` so later runs on the same Apify account back off. When the quota is hit, VAT fields become `unavailable` (or WL2 fills `vatStatus` only). The company row still succeeds if KRS or REGON identified it. The run does not fail.

On the Apify platform the egress IP can be shared. Another tenant can burn the Ministry's IP quota. The actor then degrades the same way.

#### Which insolvency entries count?

`insolvencyFlag` is true only for a **current** bankruptcy, liquidation, or restructuring entry (or a company name ending in *w upadłości*, *w likwidacji*, or *w restrukturyzacji*). Ended proceedings stay in the history list with `active: false` and do not keep the flag on. Mergers and demergers are ignored. Suspension and striking off change `status` but are not insolvency. The combined KRS section that mixes restructuring and orderly liquidation is split on the wording: text containing *likwidac* is liquidation; other wording in that section is restructuring.

#### Is a sole trader in KRS?

No. A JDG lives in CEIDG and REGON. The white list often has the name, address, REGON, and VAT status. PKD and the activity dates then need your BIR1 key. `insolvencyFlag` stays `null` because KRS was not consulted. There is no CEIDG call in this actor.

### Development

```bash
npm test
npm run build
npm run smoke
```

Vitest covers checksums, KRS current and full extracts, insolvency classification, the VAT batcher and quota breaker, monitor diffs, and the charging rules. HTTP is mocked. `npm run smoke` is the live test and is intentionally not part of CI.

### Po polsku

To narzędzie do wzbogacania danych polskich firm pod KYB, KYC i lead generation. Na wejściu podajesz NIP, REGON albo numer KRS. Na wyjściu dostajesz płaski rekord: nazwę, adres, formę prawną, kapitał zakładowy, kody PKD, zarząd i prokurentów, status na **białej liście VAT**, wynik sprawdzenia rachunku oraz wyraźną flagę upadłości, likwidacji albo restrukturyzacji.

Źródła są urzędowe i bezpłatne:

- Otwarte API KRS Ministerstwa Sprawiedliwości (`OdpisAktualny` i, na życzenie, `OdpisPelny`). API nie szuka po NIP ani REGON — numer KRS bierzemy z białej listy albo z BIR1, jeśli podasz własny klucz GUS.
- Wykaz podatników VAT Ministerstwa Finansów. Od 15 października 2026 r. adres produkcyjny to `wykazpodatnikowvat.mf.gov.pl`. Stary `wl-api.mf.gov.pl` działa do 1 grudnia 2026 r.
- Opcjonalnie REGON (BIR1), wyłącznie Twoim kluczem użytkownika, i tylko gdy KRS nie oddał nazwy, numeru REGON albo PKD. Jednoosobowa działalność nie jest w KRS.

Suma kontrolna NIP i REGON jest sprawdzana przed zapytaniem. Błędny identyfikator i brak podmiotu w rejestrze **nie są płatne**.

Cennik za zdarzenie: firma znaleziona `0,005 USD`, historia postępowań z odpisu pełnego `0,002 USD`, wykryta zmiana w trybie monitorowania `0,015 USD`. Pierwsze uruchomienie monitora zapisuje punkt odniesienia i nic nie kosztuje. Limit białej listy to 100 zapytań `search` dziennie po maksymalnie 30 podmiotów. Po wyczerpaniu limitu pola VAT dostają wartość `unavailable`, a bieg aktora się nie przerywa.

Publiczne API KRS zwraca imiona i nazwiska członków zarządu, rady nadzorczej i prokurentów w formie zamaskowanej, na przykład `D**** B****`. Pełnych nazwisk nie ma i aktor ich nie odtwarza. PESEL, jeśli w ogóle występuje, jest zamaskowany i aktor i tak go usuwa. Dziesięciocyfrowy numer bez zera na początku, który nie przechodzi sumy kontrolnej NIP, jest odrzucany jako błędny identyfikator, chyba że jawnie ustawisz typ `krs`. Numer KRS ma 10 cyfr i zera wiodące. To nie jest porada prawna ani urzędowe zaświadczenie — identyfikator zapytania `vatRequestId` wydaje Ministerstwo Finansów.

### Limitations

See [PUBLISHING.md](PUBLISHING.md) for the charge sheet. Operational limits are also collected in the FAQ above: no KRS search by NIP, shared VAT IP quota, no CEIDG, no Full KRS API, and no claim that a `local_match` IBAN check is the Ministry's TAK/NIE answer. The public KRS API masks board members' names (for example `D**** B****`), so full names are not provided.

# Actor input Schema

## `companies` (type: `array`):

One row per company. id is a NIP, REGON (9 or 14 digits), or KRS number. Prefixes such as NIP: or KRS: are accepted. checkIbans is optional and is verified against the VAT white list for that company.

## `identifierList` (type: `string`):

Optional paste area. Separate NIP, REGON, or KRS values with newlines, commas, or spaces. These rows cannot carry IBAN checks; use Companies for that.

## `includeBoard` (type: `boolean`):

Roles from the KRS extract. The public API masks personal names (for example D\*\*\*\* B\*\*\*\*), so full names are not available. PESEL is never returned.

## `includeInsolvencyHistory` (type: `boolean`):

Also fetch the full KRS extract (OdpisPelny) so ended bankruptcy, liquidation, and restructuring entries are included. In enrich mode this adds the insolvency-history charge when the extract is retrieved.

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

enrich returns one row per company. monitor stores a snapshot and returns only a free baseline, then later changes in status, address, name, board, PKD, VAT status, or insolvency entries.

## `monitorStoreName` (type: `string`):

Named key-value store that holds monitor snapshots between runs. Reuse the same name to keep the baseline.

## `regonApiKey` (type: `string`):

Optional. Your own key from GUS (regon_bir@stat.gov.pl). Used only to fill gaps, such as sole traders that are not in KRS. The key is a secret input and is not written to the dataset.

## `maxCompanies` (type: `integer`):

Fail the run instead of silently truncating when the list is longer. The VAT search quota is 100 requests per day, 30 companies each.

## Actor input object example

```json
{
  "companies": [
    {
      "id": "7740001454",
      "type": "auto",
      "checkIbans": []
    }
  ],
  "includeBoard": true,
  "includeInsolvencyHistory": false,
  "mode": "enrich",
  "monitorStoreName": "polish-company-monitor",
  "maxCompanies": 300
}
```

# Actor output Schema

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

One flat row per company in enrich mode. Monitor mode writes a baseline on the first run and only later changes.

# 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 = {
    "companies": [
        {
            "id": "7740001454",
            "type": "auto",
            "checkIbans": []
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datacraft-studio/polish-company-kyb").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 = { "companies": [{
            "id": "7740001454",
            "type": "auto",
            "checkIbans": [],
        }] }

# Run the Actor and wait for it to finish
run = client.actor("datacraft-studio/polish-company-kyb").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 '{
  "companies": [
    {
      "id": "7740001454",
      "type": "auto",
      "checkIbans": []
    }
  ]
}' |
apify call datacraft-studio/polish-company-kyb --silent --output-dataset

```

## MCP server setup

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

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/SXToneTLvcjlKKMPk/builds/hU3boRS6nluBs3phb/openapi.json
