# Poland KRS Company Lookup - Polish Company Register API (`lukehunter/poland-krs-company-lookup`) Actor

Look up Polish companies in the official KRS API (Krajowy Rejestr Sądowy) by KRS number: name, NIP, REGON, address, share capital, PKD and the board as published. $0.008 per company; not found is free.

- **URL**: https://apify.com/lukehunter/poland-krs-company-lookup.md
- **Developed by:** [Luke Hunter](https://apify.com/lukehunter) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$8.00 / 1,000 companies

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

## Poland KRS Company Lookup - Polish Company Register API

**For compliance, procurement, sales and data teams that need to check Polish companies.** Give it KRS numbers and get one clean row per company from the **KRS API** of the Polish Ministry of Justice (**Krajowy Rejestr Sądowy**, the Polish company register): name, legal form, **NIP**, **REGON**, registered address, registration date, **share capital**, **PKD** activities, and the **board as published by the register** with how the company is represented. A fast, cheap **KRS lookup** you can run from the Console, a schedule, code or an AI agent.

**$0.008 per company found. Numbers the register does not know are free. 1,000 companies = $8.**

It reads the official, free and open KRS API directly. No scraping, no login, no proxy, no API key. Only companies actually found are charged.

### What you get

One flat row per company, ready for a spreadsheet, CRM or KYB workflow:

| Group | Fields |
|---|---|
| Identity | `krs`, `nazwa` (name), `formaPrawna` (legal form), `nip`, `regon`, `register` (P or S) |
| Seat and address | `siedzibaWojewodztwo`, `siedzibaPowiat`, `siedzibaGmina`, `siedzibaMiejscowosc`, `adres` (one line), `ulica`, `nrDomu`, `nrLokalu`, `kodPocztowy`, `adresMiejscowosc`, `kraj` |
| Register dates | `dataRejestracji` (entered in the KRS), `dataOstatniegoWpisu` (last entry), `stanZDnia` (date the extract reflects) |
| Capital | `kapitalZakladowy` (share capital) and `kapitalWaluta` |
| Activity | `pkdGlowny` and `pkdGlownyOpis` (main PKD), `pkdPozostale` (list of other PKD codes) |
| Representation | `reprezentacja` (members of the representing body: `funkcja`, `nazwisko`, `imiona`), `sposobReprezentacji` (how the company is represented), `wspolnicyCount` (partners of an sp. z o.o.) |
| Optional VAT | `vatStatus`, `vatBankAccountCount`, `vatCheckedDate`, `vatLookup` (see below) |
| Provenance | `status`, `message`, `odpisType`, `sourceUrl` (the KRS API URL used), `scrapedAt` |

### Quick start

```json
{
  "krsNumbers": ["0000028860", "0000009831"],
  "maxItems": 5
}
```

KRS numbers have up to 10 digits; unpadded numbers such as `28860` are padded to `0000028860`, and a `KRS` prefix is accepted. Both registers are tried automatically: **P** (entrepreneurs, i.e. companies) first, then **S** (associations, foundations, public institutions). Set `registers: ["P"]` to ask only one.

### Recipes

**Verify Polish suppliers.** Paste the KRS numbers from your supplier master data and check that each is registered, who represents it, how, and what its capital and registered address are:

```json
{
  "krsNumbers": ["0000028860", "0000009831", "0000123456"],
  "registers": ["P"],
  "includeVatStatus": true,
  "maxItems": 500
}
```

Companies the register does not know come back as `status: "not_found"` rows, free, so a bad number in the list is visible, not silently dropped. `sposobReprezentacji` and `reprezentacja` tell you who may sign. `includeVatStatus` adds the VAT status from the Ministry of Finance white list.

**Enrich a lead list with KRS data.** Your lead list has KRS numbers; add NIP, REGON, address, capital, main PKD and the board:

```json
{
  "krsNumbers": ["0000028860", "0000009831"],
  "maxItems": 5000
}
```

Join the dataset to your list on `krs`. Filter by `kapitalZakladowy`, `pkdGlowny` or `siedzibaWojewodztwo` in your own tool. Chain the result to [Website Contact Scraper](https://apify.com/lukehunter/company-contact-scraper) to find a company's website contacts.

**Full extract.** `odpis: "full"` asks the register for the full extract (OdpisPelny) instead of the current one (OdpisAktualny). The row still contains only the values in force today, taken from the full extract; struck-out historical entries are dropped.

### NIP and REGON

The official KRS API looks a company up **by KRS number only**. It cannot resolve a NIP or a REGON to a KRS number, and this Actor does not scrape other sites to do it. If you pass `nips` or `regons` next to `krsNumbers`, each one gets a free `unsupported_identifier` row with that explanation; if you pass only NIPs or REGONs, the run stops with the same clear message and charges nothing. NIP and REGON are returned in every row for companies found by KRS number.

### VAT status (optional)

With `includeVatStatus: true` the Actor asks the Ministry of Finance **VAT white list** (`wl-api.mf.gov.pl`, search by NIP for today's date in Poland) and adds `vatStatus` (e.g. `Czynny`, active) and `vatBankAccountCount`, the **number** of bank accounts listed. It never outputs the account numbers. It is free (no extra charge), best effort, and fully optional: if the service is unavailable or refuses the request, the company is still delivered with `vatLookup: "unavailable"`, and a client error from the service switches the enrichment off for the rest of the run. `vatLookup` is `ok`, `not_registered`, `no_nip` (associations have no NIP) or `unavailable`.

### Input

| Field | Default | What it does |
|---|---:|---|
| `krsNumbers` | required | KRS numbers, up to 10 digits each, max 5,000 per run. A malformed entry stops the run with an error naming it. |
| `registers` | both | `P`, `S` or both. Empty tries P then S for each number. |
| `odpis` | `current` | `current` (OdpisAktualny) or `full` (OdpisPelny). |
| `includeVatStatus` | `false` | Add VAT status and bank-account count from the white list. |
| `maxItems` | `100` | Hard cap on delivered, charged companies, 1 to 5000. |
| `nips`, `regons` | none | Not resolvable by the KRS API; see above. |

### Example output

```json
{
  "krs": "0000900001",
  "status": "found",
  "message": null,
  "register": "P",
  "odpisType": "OdpisAktualny",
  "nazwa": "PRZYKŁADOWA SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ",
  "formaPrawna": "SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ",
  "nip": "5260000019",
  "regon": "900000019",
  "siedzibaWojewodztwo": "MAZOWIECKIE",
  "siedzibaPowiat": "M. ST. WARSZAWA",
  "siedzibaGmina": "M. ST. WARSZAWA",
  "siedzibaMiejscowosc": "WARSZAWA",
  "adres": "UL. PRZYKŁADOWA 12/4, 00-001 WARSZAWA",
  "ulica": "UL. PRZYKŁADOWA",
  "nrDomu": "12",
  "nrLokalu": "4",
  "kodPocztowy": "00-001",
  "adresMiejscowosc": "WARSZAWA",
  "kraj": "POLSKA",
  "dataRejestracji": "2015-02-03",
  "dataOstatniegoWpisu": "2026-09-22",
  "stanZDnia": "2026-10-10",
  "kapitalZakladowy": 150000,
  "kapitalWaluta": "PLN",
  "pkdGlowny": "62.01.Z",
  "pkdGlownyOpis": "DZIAŁALNOŚĆ ZWIĄZANA Z OPROGRAMOWANIEM",
  "pkdPozostale": [
    { "kod": "62.02.Z", "opis": "DZIAŁALNOŚĆ ZWIĄZANA Z DORADZTWEM W DZIEDZINIE INFORMATYKI" }
  ],
  "reprezentacja": [
    { "organ": "ZARZĄD", "funkcja": "PREZES ZARZĄDU", "nazwisko": "K*******", "imiona": "ANNA MARIA", "podmiot": null }
  ],
  "sposobReprezentacji": "W PRZYPADKU ZARZĄDU WIELOOSOBOWEGO DO SKŁADANIA OŚWIADCZEŃ W IMIENIU SPÓŁKI UPRAWNIONYCH JEST DWÓCH CZŁONKÓW ZARZĄDU ŁĄCZNIE.",
  "wspolnicyCount": 2,
  "vatLookup": null,
  "vatStatus": null,
  "vatBankAccountCount": null,
  "vatCheckedDate": null,
  "sourceUrl": "https://api-krs.ms.gov.pl/api/krs/OdpisAktualny/0000900001?rejestr=P&format=json",
  "scrapedAt": "2026-10-11T10:00:00.000Z"
}
```

This sample is illustrative (an invented company and invented people), shaped like the register's response. Anything the register does not publish is `null` or an empty list, never guessed. A number that is not found:

```json
{ "krs": "0000999999", "status": "not_found", "message": "KRS number 0000999999 was not found in register P and S. Not charged." }
```

(All other fields of that row are `null`.) `status` is one of `found` (charged), `not_found`, `error` (the register could not be read for that number), `not_processed` (not read because `maxItems`, your spending limit or the run time budget was reached) and `unsupported_identifier`. Only `found` rows are charged.

### Use with AI agents (MCP)

This Actor works as a tool for Claude, ChatGPT, Cursor and other MCP clients through [Apify's MCP server](https://mcp.apify.com). The only required input is `krsNumbers`, and each input property description is short and carries an example, so agents fill it in correctly.

**Claude Desktop** (`claude_desktop_config.json`), with your own token from Apify Console > Settings > API & Integrations:

```json
{
  "mcpServers": {
    "apify-poland-krs-company-lookup": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mcp.apify.com?tools=lukehunter/poland-krs-company-lookup",
        "--header", "Authorization: Bearer ${APIFY_TOKEN}"
      ],
      "env": { "APIFY_TOKEN": "<YOUR_APIFY_TOKEN>" }
    }
  }
}
```

Clients that support OAuth (Claude.ai, VS Code) can connect with just the URL `https://mcp.apify.com?tools=lukehunter/poland-krs-company-lookup` and sign in to Apify. Never paste a real token into a shared file or chat.

**Example.** You ask: "Who can sign for PKN Orlen and what is its share capital?" The agent calls the tool `lukehunter--poland-krs-company-lookup` with:

```json
{
  "krsNumbers": ["0000028860"],
  "registers": ["P"],
  "maxItems": 1
}
```

It is charged $0.008 for the one company found, capped by `maxItems`.

### Pricing

Pay-per-event: **$0.008 per company found** (event `company`). Numbers not found, read errors, unsupported NIP/REGON inputs and `not_processed` rows are free, and so is the optional VAT status.

| Companies found | Cost |
|---:|---:|
| 5 | $0.04 |
| 100 (default cap) | $0.80 |
| 1,000 | $8.00 |
| 5,000 (maximum) | $40.00 |

For comparison, other Polish KRS actors on the Apify Store were listed in October 2026 at between $0.0065 and $0.06 per lookup; this one is $0.008 for the same register data. `maxItems` (hard maximum 5,000) and your Apify per-run spending limit both stop delivery before the cap is passed: a company is delivered and charged together, and never past your limit. Price changes follow Apify's notice rules; the Pricing tab always shows the rate you are charged.

### Limitations

- **Official open data; attribute it.** The data comes from the open KRS API of the Polish Ministry of Justice (Krajowy Rejestr Sądowy) and is public-sector information. If you republish it, name the source: "Source: Krajowy Rejestr Sądowy (KRS), Ministry of Justice of Poland." This Actor is independent and not affiliated with the Ministry; the register's own extracts are the authoritative record for legal purposes.
- **By KRS number only.** The KRS API has no name search and cannot resolve NIP or REGON (see above). Get the KRS number from your own records, a contract or an invoice.
- **Registered companies only.** KRS covers companies, partnerships, cooperatives, associations, foundations and similar entities. Sole traders (CEIDG) are not in it.
- **Surnames are masked by the register.** The KRS open API publishes board members' surnames masked (for example `F*****`) and first names in full. This Actor passes them through exactly as published and never tries to unmask them. For full names, use the official register extract (odpis) from the Ministry of Justice portal.
- **Board members are personal data.** `reprezentacja` has the function, surname and first names of the members of the representing body, exactly as the register publishes them by law so that third parties know who can bind the company. No PESEL, birth date or private address is output, and neither are partners' or supervisory board members' names. If you store or use these names, do so in line with the GDPR.
- **Shape of the register's answer.** Optional blocks differ between legal forms (for example, partners are counted only for an sp. z o.o.; associations have no capital or NIP). Missing values are `null`.
- **Rate limits.** The register publishes no limit; this Actor sends about 2 requests per second, one at a time, and retries 429 and 5xx answers with backoff. If it stays unavailable for five lookups in a row the run stops and charges nothing for the rest. A run stops reading after 30 minutes and lists the unread numbers as `not_processed`.
- **VAT white list.** The optional enrichment depends on a separate Ministry of Finance service that may refuse or fail; the company is delivered either way.

### Use it from your code, Make, Zapier or n8n

Built for automated pipelines: small runs, stable field names, one row per item, and you pay only for rows actually delivered.

**One API call that runs the Actor and returns the data** (replace `$APIFY_TOKEN` with your token from Apify Console → Settings → Integrations):

```bash
curl -s -X POST "https://api.apify.com/v2/acts/lukehunter~poland-krs-company-lookup/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"krsNumbers": ["0000028860", "0000009831"], "maxItems": 5}'
```

**JavaScript** (`npm i apify-client`):

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lukehunter~poland-krs-company-lookup').call({
  "krsNumbers": [
    "0000028860",
    "0000009831"
  ],
  "maxItems": 5
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**Python** (`pip install apify-client`):

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('lukehunter~poland-krs-company-lookup').call(run_input={"krsNumbers": ["0000028860", "0000009831"], "maxItems": 5})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

**Schedules, webhooks and no-code tools:** save your input as a Task, add a Schedule (e.g. hourly or daily), and attach a webhook or one of the Integrations tab's connectors (Make, Zapier, n8n, Google Sheets, Slack) to push each run's results into your own system.

**Feedback:** an honest rating on the Store page, good or bad, helps others decide if this Actor fits their needs. Missing a field or found a problem? Open an issue on the Actor page.

### FAQ

**Is this the official KRS API?** It reads the official KRS open API (api-krs.ms.gov.pl) of the Ministry of Justice. This Actor flattens the extract to one row per company, handles both registers and the full extract, retries politely and bills only for companies found.

**What is a KRS number?** The 10-digit number under which an entity is entered in the Krajowy Rejestr Sądowy. It is printed on Polish company letterheads, contracts and invoices, usually as "KRS 0000028860".

**What is the difference between register P and S?** P is the register of entrepreneurs (companies and partnerships), S the register of associations, other social and professional organisations, foundations and public healthcare institutions. Leave `registers` empty and both are tried.

**Can I look a company up by NIP, REGON or name?** Not with the KRS API; see "NIP and REGON". Use the KRS number.

**Why did I get a not_found row?** The number is not entered in the register you asked for (try both registers), or it has a typo. Not found is free.

**Does it contact companies or people?** No. It only reads the register and reports.

### Related Actors

Other data tools from the same developer, built to the same standard: official or public sources, hard cost caps, and honest documentation of limits.

- **[Domain Email Provider Lookup](https://apify.com/lukehunter/email-provider-mx-lookup)**: the email provider (Google Workspace, Microsoft 365, Zoho and more), MX, SPF and DMARC setup of any domain list, with provider-change alerts.
- **[French Company Leads](https://apify.com/lukehunter/french-companies-sirene)**: French companies (entreprises) from the official Sirene-based API, filtered by NAF code, department, headcount and creation date, with SIREN/SIRET, officers and new-company alerts.
- **[Website Contact Scraper](https://apify.com/lukehunter/company-contact-scraper)**: emails, phone numbers and social profile links from any list of company domains, with the page each came from and a changed-contacts-only mode for scheduled runs.
- **[Impressum Scraper](https://apify.com/lukehunter/impressum-scraper)**: legal entity data from the imprint of any company website in Germany, Austria and Switzerland: legal name and form, managing directors, HRB/HRA or FN register, VAT id and address, with a changed-data-only mode for scheduled runs.
- **[Website Tech Stack Detector](https://apify.com/lukehunter/website-tech-stack-detector)**: the technologies a website runs (CMS, ecommerce platform, analytics, ad pixels, chat, payments, CDN, frameworks) from its home page, with the evidence for each match and a changed-technologies-only mode for scheduled runs.
- **[Google Maps Email Extractor & Lead Enricher](https://apify.com/lukehunter/lead-enricher)**: emails, phones, social links, named people and the tech stack of every business in your Google Maps Scraper results, one enriched row per business, with filters such as only Shopify stores with an email.
- **[Federal Register Rule Effective-Date Radar](https://apify.com/lukehunter/federal-rule-effective-date-radar)**: final federal rules about to take effect, with citations, dockets and urgency.
- **[UK Tenders Monitor](https://apify.com/lukehunter/uk-tenders-monitor)**: new UK public-sector tenders from Contracts Finder and Find a Tender, filtered by CPV code, value, region and buyer, with Slack, Discord and Telegram alerts.

# Actor input Schema

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

KRS numbers to look up, up to 10 digits each, e.g. \["0000028860", "0000009831"] (PKN Orlen, PZU). Unpadded numbers such as 28860 are padded to 10 digits. A malformed entry stops the run with an error. Not-found numbers are free. Max 5,000 per run.

## `registers` (type: `array`):

Register to search: P = entrepreneurs (companies), S = associations, foundations and public institutions, e.g. \["P"]. Leave empty to try P first and then S for each number (an unknown number then costs two requests).

## `odpis` (type: `string`):

current = OdpisAktualny, the extract in force today (default, e.g. for supplier checks). full = OdpisPelny, the full extract including history; the Actor still returns only the values in force today, from the full extract.

## `includeVatStatus` (type: `boolean`):

Also ask the Ministry of Finance VAT white list about each company's NIP and add the VAT status and the number of bank accounts listed (never the account numbers), e.g. true. Free, best effort: if the service fails the company is still delivered.

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

Hard cap on delivered (charged) companies, 1 to 5000, e.g. 100. At $0.008 per company 100 companies cost $0.80. Numbers not read because the cap was reached are listed as not_processed rows, free.

## `nips` (type: `array`):

Optional, e.g. \["7740001454"]. The KRS API cannot look up a NIP, and this Actor does not scrape other sites to resolve it, so each NIP gets a free unsupported_identifier row, and a run with only NIPs fails with a clear message. Give KRS numbers instead.

## `regons` (type: `array`):

Optional, e.g. \["610188201"]. The KRS API cannot look up a REGON, so each one gets a free unsupported_identifier row, and a run with only REGONs fails with a clear message. NIP and REGON are returned for every company found by KRS number.

## Actor input object example

```json
{
  "krsNumbers": [
    "0000028860",
    "0000009831"
  ],
  "odpis": "current",
  "includeVatStatus": false,
  "maxItems": 5
}
```

# Actor output Schema

## `companies` (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",
        "0000009831"
    ],
    "maxItems": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("lukehunter/poland-krs-company-lookup").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",
        "0000009831",
    ],
    "maxItems": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("lukehunter/poland-krs-company-lookup").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",
    "0000009831"
  ],
  "maxItems": 5
}' |
apify call lukehunter/poland-krs-company-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lukehunter/poland-krs-company-lookup"
        }
    }
}
```

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/f4j4GaLioJLadVIf3/builds/UPJr69pf6nWg7vfdS/openapi.json
