VAT white list check in n8n: verify Polish contractors from a sheet before paying
A list of contractors in Google Sheets, and before every transfer someone pastes tax numbers into the Ministry of Finance search page by hand. This n8n workflow does it instead: it validates the NIP, queries the white list API, compares the bank account and returns a plain verdict.
Author
- Adrian HuniaCo-founder of SEVENEDGE
- Published:
- Last verified:
- n8n version:
- 2.8.4
In short
What it does
- Reads contractors from Google Sheets on demand or on weekdays at 7:00
- Normalises the NIP and checks its checksum locally
- Queries the Ministry of Finance VAT register API for today's status
- Compares the bank account in the sheet with the accounts in the register
- Returns ACTIVE, NOT_ACTIVE, NOT_FOUND or INVALID_NIP
What it does not do
- Does not write results back to the sheet
- Does not keep the request ID as proof of the check
- Cannot get around the limit of 100 requests a day
- Is not tax advice
What it needs
- n8n (tested on 2.8.4)
- A Google account with access to the sheet
- Columns: NIP, company name, optionally the bank account
VAT white list check in n8n: verify Polish contractors from a sheet before paying
In Poland, anyone paying an invoice above 15,000 PLN should check that the supplier's bank account is in the VAT taxpayer register, known as the white list. In small companies the routine looks the same everywhere: a spreadsheet of contractors and someone pasting tax numbers one by one into the Ministry of Finance search page.
This n8n workflow takes that job over. It reads the sheet, drops invalid tax numbers, queries the official API and returns one of four verdicts per row.

Checksum first, API second
A Polish NIP has a check digit. A typo in the sheet can be caught without asking anyone, so the first step normalises the number (dashes and spaces removed) and checks the weights.
function checksumOk(nip) {
if (!/^\d{10}$/.test(nip)) return false;
const w = [6, 5, 7, 2, 3, 4, 5, 6, 7];
const sum = w.reduce((acc, weight, i) => acc + weight * Number(nip[i]), 0);
return sum % 11 === Number(nip[9]);
}
A NIP that fails this check gets INVALID_NIP, whatever the API says.
Four verdicts instead of a raw response
The API returns result.subject with a statusVat field. An active taxpayer has the value "Czynny" there. The workflow reduces this to four states anyone can read without knowing the API:
| Verdict | Meaning |
|---|---|
ACTIVE | active VAT taxpayer on the date checked |
NOT_ACTIVE | in the register, but with a status other than active |
NOT_FOUND | the register does not know this NIP on that date |
INVALID_NIP | the number failed the checksum |
If the sheet has a bank account column, the workflow compares it with the accountNumbers list from the register (spaces removed). account_on_white_list is then true or false. Without the column it stays empty, because missing data is not the same as a negative result.
The output starts with a summary such as "3 of 40 contractors need attention before payment". That is the one number someone looks at every morning.
The API limit
For longer lists you need batched requests (up to 30 NIPs at once) or to split the sheet across days.
Configuration
| Parameter | Default | Purpose |
|---|---|---|
whiteListApi | https://wl-api.mf.gov.pl/api/search/nip/ | the NIP search method |
nipColumn | NIP | column with the tax number |
nameColumn | Company | column with the name, used if the register returns none |
accountColumn | Bank account | column with the account to compare |
The schedule is weekdays at 7, before anyone starts making transfers.
Limitations
The result stays in the n8n execution. The template does not write verdicts to the sheet or send an alert, so when it runs on the schedule you need to add one of those steps. Otherwise the morning run tells nobody anything.
A NIP rejected by the checksum still reaches the HTTP node, which fails and is skipped. With 100 requests a day it is better to filter those rows out before the request.
The API response contains a request ID that can serve as proof the account was checked. The template does not store it.
The check is for the day of the run, not the day of the transfer. If payment goes out a few days later, check again.
When it does not make sense
With a handful of regular suppliers a manual check takes a minute, and some banks check the register when you order a transfer. The workflow makes sense when there are dozens of contractors and the payment list is prepared in a spreadsheet before it goes to the bank. If the same should happen inside your accounting system or a team panel, that becomes a process automation project for your company, and for company records you can also enrich companies from a NIP with KRS data.
Take it with you
How to cite this
Adrian Hunia (2026). VAT white list check in n8n: verify Polish contractors from a sheet before paying. SEVENEDGE. https://sevenedge.pl/en/workflows/biala-lista-vat-weryfikacja-kontrahentow (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.


