For developers · REST and MCP

KRS API by NIP
keyless REST/JSON

Data from Poland's National Court Register (KRS) by tax ID (NIP), with a single GET that returns clean JSON. No API key, no sign-up. You do not need the KRS number: the lookup is by NIP, and the response gives you the legal form, share capital, board, representation rules and PKD activity codes.

One GET, one JSON

The endpoint is public, the method is GET, and the ?format=json parameter returns machine-readable data (without it you get an HTML page for humans). The KRS data lives in the krs field:

curl "https://skanfirmy.pl/nip/5260250995?format=json"

The krs field gives you the full register record — the KRS number, name, legal form, share capital, the representation body together with the representation rule, the board members and PKD codes:

{
  "krs": {
    "numerKRS": "0000010681",
    "nazwa": "ORANGE POLSKA SPÓŁKA AKCYJNA",
    "formaPrawna": "SPÓŁKA AKCYJNA",
    "nip": "5260250995",
    "regon": "012100784",
    "opp": false,
    "adres": "AL. JEROZOLIMSKIE 160, 02-326, WARSZAWA",
    "kapital": "3937072437,00 PLN",
    "organ": "ZARZĄD SPÓŁKI",
    "sposobReprezentacji": "PREZES ŁĄCZNIE Z CZŁONKIEM ZARZĄDU",
    "sklad": ["CZŁONEK ZARZĄDU", "..."],
    "pkdMain": [{ "code": "61.10.B", "opis": "POZOSTAŁA DZIAŁALNOŚĆ W ZAKRESIE TELEKOMUNIKACJI ..." }],
    "pkdOther": [{ "code": "78.10.Z", "opis": "..." }],
    "dataRejestracji": "02.05.2001",
    "dataOstatniegoWpisu": "24.04.2026",
    "stanZDnia": "24.04.2026",
    "dataCzasOdpisu": "25.08.2026 14:59:57"
  }
}

No API key, no sign-up

The endpoint works right away: no account to create, no API key to generate. That is a deliberate difference from commercial KRS wrappers: the goal is an integration you can wire up in a minute, including from an AI agent. The service is maintained free of charge; for heavy automated traffic we only ask for common sense (single lookups triggered by users, not bulk scraping).

Lookup by NIP, not by KRS number

The official KRS API from the Ministry of Justice is looked up by KRS number — you need to have it from somewhere first, and the response is a full extract in an elaborate JSON structure (separate sections, divisions and entries). In practice you usually have the NIP, not the KRS number. Our endpoint takes the NIP, finds the right entry server-side, and returns a flat, ready-to-use set of fields.

What the krs field in the /nip/{nip} response returns:

FieldMeaning
numerKRSNumber in the National Court Register
nazwa, formaPrawnaOfficial name and legal form (e.g. SPÓŁKA AKCYJNA — joint-stock company, SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ — limited liability company)
kapitalShare capital (for capital companies)
organ, sposobReprezentacjiBody authorised to represent the company and the representation rule (who may sign on the company's behalf, and how)
skladList of people in the representation body (board members)
pkdMain, pkdOtherPKD codes — main and other — each as { code, opis }
dataRejestracjiDate of the first entry in KRS
oppPublic-benefit organisation flag (true/false)

If an entity is not in KRS (e.g. a sole proprietorship registered only in CEIDG), the krs field is null and a krsError field may explain why. In that case use the REGON register via /regon/{nip}.

In Python

With the requests library it is a few lines:

import requests

def krs_data(nip: str) -> dict | None:
    r = requests.get(f"https://skanfirmy.pl/nip/{nip}?format=json", timeout=10)
    r.raise_for_status()
    return r.json().get("krs")

k = krs_data("5260250995")
if k:
    print(k["formaPrawna"], "·", k["kapital"])
    for member in k["sklad"]:
        print(" -", member)
# SPÓŁKA AKCYJNA · 3937072437,00 PLN

A NIP with an invalid checksum returns 400, and an entity that is not in KRS has krs: null — it is worth handling both instead of assuming every NIP has a court-register entry.

In JavaScript

const r = await fetch("https://skanfirmy.pl/nip/5260250995?format=json");
const { krs } = await r.json();
if (krs) {
  console.log(krs.formaPrawna, krs.kapital);
  console.log(krs.pkdMain[0].code, krs.pkdMain[0].opis);
}

In PHP

$ch = curl_init("https://skanfirmy.pl/nip/5260250995?format=json");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$krs = json_decode(curl_exec($ch), true)["krs"];
if ($krs) {
    echo $krs["formaPrawna"] . " · " . $krs["kapital"];
}

More than KRS, from one NIP

The same /nip/{nip}?format=json endpoint, besides the krs field, also returns the VAT status from the VAT taxpayer register (White List, Ministry of Finance) and the REGON number — all in one response. The other endpoints (all GET → JSON, no key):

  • /nip/{nip} — VAT status + White List + KRS + REGON
  • /regon/{nip} — data from the REGON register (GUS)
  • /nips/{list} — several NIPs at once (comma-separated)
  • /vies/{country}/{number} — EU VAT number validation (VIES, European Commission)

For AI agents, at https://skanfirmy.pl/mcp there is a Model Context Protocol (MCP) server with a sprawdz_nip tool that returns the same krs field (and several others for REGON, VIES and NIP lists), also with no key. A model-readable map of the endpoints is in llms.txt. For a lookup in the UI, use the KRS data tool.

The public endpoint vs a typical paid KRS API

Most commercial REST wrappers over KRS run on a freemium model — an account, an API key and a daily request limit on the free tier — and on top of that they look up by KRS number. This endpoint is public, free, and takes a NIP. The differences in short:

Typical paid KRS APIskanfirmy.pl /nip (krs field)
API keyrequirednot needed
Registration / accountyesno
Free-tier limitusually yesno hard limit (please be reasonable)
Response formatREST/JSONREST/JSON
MCP server for AI agentsusually noneyes
Lookupby KRS numberby NIP
Modelfreemium / subscriptionfree

This is not the official KRS API — the data comes from the same source (the National Court Register, Ministry of Justice), just exposed with a single GET request by NIP.

Where the data comes from, and what this is not

The data comes straight from the National Court Register (KRS) kept by the Ministry of Justice. This is an independent tool; it is not the official KRS API and is not affiliated with it — it only exposes KRS data in a more convenient form. PKD codes and their descriptions are Poland's legal business classification and are returned as-is (not translated), even on this English page. The scope and freshness of the data match the KRS register.

Frequently asked questions

Do I need the KRS number to get the data?

No. The lookup is by NIP — send a GET to /nip/{NIP}?format=json, and you will find the KRS number in the response (the krs.numerKRS field). You do not need it upfront. This is a difference from the official KRS API, which looks up by KRS number.

Do I need an API key or to sign up?

No. The /nip/{nip} endpoint is public — it returns JSON once you add ?format=json, with no API key and no account. The KRS data is in the krs field.

What KRS data does this API return?

The krs field contains the KRS number, name, legal form, share capital, the body and rule of representation, the board members (sklad), the main and other PKD codes (pkdMain, pkdOther), the registration date and a public-benefit organisation flag (opp).

What if a company is not in KRS?

Then the krs field is null and a krsError field may explain why — for example a sole proprietorship registered only in CEIDG. In that case use the /regon/{nip} endpoint, which draws on the REGON register.

Is it free to use?

Yes. The endpoint is free and requires no registration. The data comes straight from the National Court Register kept by the Ministry of Justice.