NIP, VAT white list and KRS in one row: enriching Polish company data in n8n
Your sheet holds nothing but Polish tax numbers, and you need the name, REGON, legal form, board members, PKD code and bank accounts. This n8n workflow queries two public registers, the VAT white list and the KRS court register, and writes the result back into the same row.
Author
- Adrian HuniaCo-founder of SEVENEDGE
- Published:
- Last verified:
- n8n version:
- 2.8.4
In short
What it does
- Reads NIPs from Google Sheets and validates their checksum
- Fetches VAT status, REGON, address and bank accounts from the white list
- Takes the KRS number from the white list response and fetches the KRS extract
- Extracts legal form, board members, main PKD code and registered address
- Writes everything back into the same sheet row
What it does not do
- Covers sole traders only with white list data (CEIDG needs an API key)
- Does not query the register of associations and foundations
- Does not score the company, it only collects data
- Cannot get around the Ministry API limit of 100 requests a day
What it needs
- n8n (tested on 2.8.4)
- A Google account with access to the sheet
- A NIP column in the sheet
NIP, VAT white list and KRS in one row: enriching Polish company data in n8n
A list of leads, suppliers or contractors in Poland often starts with nothing but a NIP, the Polish tax number. The rest, meaning the name, REGON, legal form, board members, line of business and the accounts the company accepts payments on, sits in two public registers. Both have free APIs.
This n8n workflow combines them into one sheet row. Neither register needs an API key.

The KRS number comes from the white list
The KRS API takes a KRS number, not a NIP. Instead of asking the user for a second identifier, the workflow first queries the VAT white list, which returns a krs field, and only then fetches the current extract from KRS:
wl-api.mf.gov.pl/api/search/nip/{NIP}?date={today}
api-krs.ms.gov.pl/api/krs/OdpisAktualny/{KRS from the response}?rejestr=P&format=json
A company without a KRS entry (a sole trader, for example) gets the white list data, and the KRS fields stay empty.
A KRS extract has no single shape
The extract's structure depends on the legal form. The board of a limited company and the partners of a general partnership sit under different keys, and first names come either as an array of objects or as plain text. Rather than map every path, the code searches the tree for keys:
const dane = odpis ? findDeep(odpis, 'danePodmiotu') : null;
const header = odpis ? findDeep(odpis, 'naglowekA') : null;
const pkd = odpis ? findDeep(odpis, 'przedmiotDzialalnosci') : null;
People are collected from section 2 of the extract as "name surname (role)", de-duplicated, up to 12.
Two details that make Google Sheets reject the update
The second detail: an auto-mapped update dislikes mixed types. A boolean in one column and text in the next can be enough for an error. Everything goes out as text, and empty values become empty cells rather than the word "null".
What lands in the sheet
| Column | Source |
|---|---|
vat_status, name_vat, regon, address_vat | white list |
bank_accounts | white list, up to 5 accounts, the rest as "+N more" |
legal_form, name_krs, krs_registered_since | KRS |
people | KRS, section 2 |
pkd_main | KRS, main line of business |
checked_at | date of the check |
Limitations
Sole traders have no KRS entry. Their registration data is in CEIDG, whose API needs a token, so this workflow does not use it.
The request goes only to the business register (rejestr=P). Associations and foundations are in register S and get no KRS data.
Each company takes two requests. The Ministry API allows 100 requests a day, so longer lists have to be split across days. A NIP with a bad checksum still reaches the request (it fails and is skipped), so filter those out earlier.
The deep key search is a heuristic. For an unusual legal form a field may stay empty even though the information is in the extract.
When it does not make sense
For a few companies the register search pages are faster. The workflow is useful for lists in the hundreds, for example when preparing a sales database or reviewing suppliers. Right before payment, a separate workflow that checks contractors against the white list fits better. When register data should flow straight into a CRM or purchasing system, that is a process automation project.
Take it with you
How to cite this
Adrian Hunia (2026). NIP, VAT white list and KRS in one row: enriching Polish company data in n8n. SEVENEDGE. https://sevenedge.pl/en/workflows/nip-krs-biala-lista-wzbogacanie-firm (accessed: November 5, 2026)
Sources
Who is behind this
Adrian Hunia
Co-founder of SEVENEDGE
Co-founder of SEVENEDGE. Designs and deploys business systems for small companies, from production management to time tracking. Works with Next.js, FastAPI and PostgreSQL. SEVENEDGE has no subcontractors — both owners write the code.
Related documents
Other workflows we documented the same way.
- Contract review against your playbook: clause by clause, with a gate for the lawyerA contract lands in a folder, Claude extracts the clauses, an agent assesses each one against your negotiating positions, and code computes the verdict. While writing this up we found a bug in the published version that dropped two of every three assessments. We describe it here along with the fix.
- A three-agent AI support desk: triage, documentation research, reply draft and a human gateOne agent classifies the ticket, a second looks for the answer in your own documentation, a third drafts the reply. Only a reply that passes three conditions at once goes out on its own. A person sees the rest, and every question your docs cannot answer becomes a documentation task.


