Monitoring · VAT White List

Contractor monitoring
on the VAT White List

You give us the tax IDs (NIP) of the companies you work with, and once a day we compare their entry in the Wykaz Podatników VAT — the Polish VAT taxpayer register, known as the White List — against the previous day. When a contractor's VAT status, list of bank accounts or registry data shown in the White List — name, address, KRS or REGON (for natural persons running a business only the VAT status and accounts) — changes, you get an e-mail; if you are wiring this into your own system, you can also receive a webhook or read it from the API. We watch up to 10 tax IDs per address, at no charge and with no account to create.

How monitoring works

Four steps. Your first notification usually arrives a day after you confirm the sign-up — sooner if the number is already on file.

1. You add tax IDs

Enter your e-mail address and the tax IDs of your contractors — up to ten. No account, no password.

2. You confirm the sign-up

Click the link in the message we send to that address. The confirmation page shows your API key once — save it if you plan to integrate, because we cannot issue it again.

3. We check once a day

At 06:00 UTC we query the official Ministry of Finance API. When a number is new to us, we record its starting state and deliberately send nothing — there is nothing to compare against yet.

4. We write only on a change

A message goes out only when the entry actually changed. Silence usually means nothing happened in the register — the full history is in the API either way.

Up to ten numbers per address. We watch by tax ID. Sole traders (tax IDs without a KRS number) are watched in a narrower scope: VAT status and bank accounts (masked). Validation messages from the server are returned in Polish.

By signing up you accept the terms of service. By clicking the link in the email you confirm your address and agree to receive email notifications about the companies you watch — you can unsubscribe at any time. How we process data: privacy policy, section 6. The confirmation link is valid for 24 hours; we send at most two such messages per address per day. The unsubscribe link is in the footer of every notification.

A contractor's status changes between the contract and the payment

Contractor verification is usually a one-off: you check a company when the relationship starts, and come back to it only when something goes wrong. Meanwhile the entry in the VAT White List keeps moving — a taxpayer can be struck off the register, reinstated, and can change the bank accounts they have reported. Nobody notifies you about any of this.

That matters for business payments of PLN 15,000 and above: paying into an account that is not in the register can mean the expense is not deductible and can trigger joint liability for the contractor's VAT (art. 15d CIT / art. 22p PIT — Polish provisions denying the tax-deductible cost). The account number you checked a quarter ago is not necessarily the one that applies today.

Monitoring closes that gap: instead of remembering to re-check every contractor, you get a signal when something has changed. You should still verify the account on the day of the transfer — only that check returns a confirmation identifier from the Ministry of Finance. This is general information, not tax advice; discuss the consequences of a specific payment with your accountant.

What we monitor, and what we do not

We compare the VAT White List entry field by field and detect two groups of events — status and settlements, and the entity's registry data (only for entities with a KRS number) — all as they appear in the White List:

  • status_vat — a change in the taxpayer's status, for example being struck off the register or reinstated.
  • account_added — a new bank account appeared in the register.
  • account_removed — an account disappeared from the register.
  • name — a change of the entity's name (entities with a KRS number only; since 27 Sep 2026 we do not track it for natural persons running a business).
  • address — a change of the entity's address (entities with a KRS number only; since 27 Sep 2026 we do not track it for natural persons).
  • krs — a change of the KRS number (entities with a KRS number only).
  • regon — a change of the REGON number (entities with a KRS number only).

Name, address, KRS and REGON come from the same White List entry — we do not separately query the KRS court register or the REGON (GUS) database, so we detect a change in this data only once the White List reflects it. We do not track these changes for natural persons running a business.

Out of scope is data the White List does not carry: proceedings and details in KRS and CEIDG (board composition, PKD activity codes, legal form), REGON data beyond the number itself, bankruptcy and restructuring proceedings, financial statements, debtor registers, and VIES status. We monitor the VAT White List entry, not the health of the business.

In the e-mail the account number is masked — 12…3456 (the two check digits and the last four) — together with a link to the full data. The full number is delivered through technical channels only: in the API response, in the MCP tools and in the webhook call. One exception: for natural persons running a business (entities without a KRS number) every channel — e-mail, API, MCP and webhook — carries only the masked account (since 26 Sep 2026), and since 27 Sep 2026 we watch only the VAT status and accounts: we neither store nor send the name or town (the name field is null), and we do not track name or address changes (GDPR). The natural_person field in the API, MCP and webhook tells you which case applies. To check whether a specific account from an invoice is on the White List, use POST /rachunek or the account check tool. An alert is a signal, not evidence of due diligence — that remains the account check with its confirmation identifier.

Who uses this

Most often accounting offices watching a stable list of clients, companies settling with a recurring group of suppliers, and teams that feed the change signal straight into their finance system. If instead of watching a fixed list you need to check many numbers at once, use bulk checking.

Integrations: REST, MCP and webhooks

Monitoring was built for machines as well as people. Three channels operate on the same state: a REST interface, an MCP server for AI agents, and a webhook. You receive the API key once, on the sign-up confirmation page — there is no endpoint to recover or rotate it.

Authorization: Bearer sk_live_…
X-API-Key: sk_live_…            # alternative; in MCP also the api_key argument

Signing up needs no key — it is the same endpoint the form above uses. We start watching numbers only after you click the link in our message — also when you add them to an already confirmed address (with an API key you add them without an e-mail, via /api/observe):

POST https://skanfirmy.pl/observe
Content-Type: application/json

{"email":"accounting@example.com","nips":["1234563218"]}

You read the change history with GET — it covers changes from the day you started watching a number. The limit parameter defaults to 100 and is clamped to the range 1–500; since is compared against the scan date, not an exact timestamp. Note that current_status_vat carries the literal value returned by the register, in Polish:

GET https://skanfirmy.pl/changes?since=2026-08-01&limit=100
Authorization: Bearer sk_live_…

{
  "since": "2026-08-01",
  "count": 1,
  "changes": [{
    "nip": "1234563218",
    "changed_at": "2026-08-14",
    "field": "account_removed",
    "old_value": "61109010140000071219812874",
    "new_value": null,
    "name": "PRZYKŁADOWA SP. Z O.O.",
    "current_status_vat": "Czynny",
    "current_vat_active": true,
    "current_status_vat_code": "active",
    "natural_person": false
  }]
}

Alongside the raw literal current_status_vat (exactly what the MF register said) every entry carries language-neutral derived fields: current_vat_active (a boolean, true only for „Czynny”) and current_status_vat_code (active/exempt/not_registered). When a number has not been checked even once, the derived fields are simply absent — their absence does not mean “not registered”. Likewise, GET /api/observations returns vat_active and status_vat_code next to status_vat.

Three calls manage the list: POST /api/observe adds numbers, GET /api/observations returns the watched entries along with the last check, and POST /api/unobserve ends the watch of a single number (the watch is deleted right away). A last_changed: null value means we have not recorded any change for that number yet — or that we have not managed to check it even once. The date belongs to the number, not to your sign-up.

You register a webhook with POST /api/webhook; the response shows the secret once. You disable it with DELETE — an empty address in POST returns an error. We accept https addresses only, no IP literals or local names, and we do not follow redirects. Delivery is two attempts in a single run, then a retry on the next check; it is at-least-once, so deduplicate on the X-Skanfirmy-Delivery header:

X-Skanfirmy-Event: nip.change
X-Skanfirmy-Delivery: 4821
X-Skanfirmy-Timestamp: 1786089600
X-Skanfirmy-Signature: sha256=9f2c…

{"id":4821,"type":"nip.change","nip":"1234563218","field":"account_added",
 "old_value":null,"new_value":"61109010140000071219812874",
 "name":"PRZYKŁADOWA SP. Z O.O.","changed_at":"2026-08-14","natural_person":false}

The signature is HMAC-SHA256 over the secret, computed on the timestamp, a dot, and the raw request body. Compare it in constant time and reject timestamps older than a few minutes.

AI agents use the MCP server at /mcp — the tools observe_nip, unobserve_nip, list_observations, changes_since and set_webhook operate on the same state as REST. Two differences are worth knowing: changes_since returns at most 200 changes and omits the current_status_vat field, and set_webhook with an empty address disables the channel (in REST that is what DELETE is for). The full machine-readable description lives in llms.txt.

Your data and unsubscribing

Your e-mail address is used only to deliver the notifications you asked for and to handle sign-up and unsubscribe. As proof of consent we store the date and IP address of the confirmation of your address and of every later request for numbers made through the form (with the list of requested tax IDs), and keep it for 3 years after you unsubscribe, then delete it. The log of sent notifications is kept for up to 90 days, the change history of watched numbers for up to 90 days, and an unconfirmed request is deleted after 7 days.

To detect a change at all, we store the last known state of every watched number (for natural persons running a business — only the VAT status and masked accounts, no name or town). We do not build a copy of the whole register — we keep the current state only for numbers somebody is watching, and delete it once the last person stops watching that tax ID. The detected changes themselves stay in the 90-day history, including after you unsubscribe.

You unsubscribe through the link in the footer of every notification — opening it lets you confirm with a single button, and we delete all your watches, your API key and webhook settings at once. You can end the watch of a number at any time through the API — we then stop checking it and send no notifications about it. We delete the watch right away — the number doesn't stay on your list. We block an address when messages to it bounce permanently or are reported as spam — since 29 September 2026 we copy this from Brevo's block list every day; we can also block an address manually. If sign-up does not go through, write to info@skanfirmy.pl. Section 6 of the privacy policy has the details.

Changes to this page — 27 Sep 2026: for natural persons running a business (entities without a KRS number) we watch only the VAT status and masked accounts — we neither store nor send the name or town (name = null) and we do not track name, address, KRS or REGON changes; such data stored earlier has been deleted. The /changes example now shows current_vat_active and current_status_vat_code, as the Polish page does. 26 Sep 2026: for natural persons running a business (entities without a KRS number) accounts only in masked form and the town instead of the address — in every channel and in the stored state; new natural_person field in the API, MCP and webhook. 25 Sep 2026: new numbers (including ones added to an already confirmed address) are watched only after e-mail confirmation; the API key is accepted only in a header (no ?api_key= in the URL); the change history covers the period since you started watching a number; after you unsubscribe we delete your watches, API key and webhook settings; proof of consent is kept for 3 years after you unsubscribe.

Scope of the service and limits

There is no charge, within a limit of ten tax IDs per e-mail address. Every channel — e-mail notifications, the API key, MCP access and webhooks — sits within that same scope. There is no price list and no paid tier.

Some numbers cannot be watched — the service does not present their data. Watches of such numbers are paused without notice, and removed once the exclusion is final. This may also affect a number you watch.

I run this as a sole trader, without a service level agreement. Checks depend on the availability of the Ministry of Finance API: once its daily quota is exhausted, some numbers are only checked the following day. This is not real-time monitoring — up to a day can pass between a change in the register and your notification. Larger lists and integrations with accounting systems are arranged individually — write to info@skanfirmy.pl or see the services page.

Frequently asked questions

Is watching contractors' tax IDs legal?

Yes. The VAT White List is a public register maintained by the Polish Ministry of Finance and anyone may query it. Monitoring only automates something you are already allowed to do by hand — checking the status of a company you settle accounts with. We do not tell the watched entity that somebody is watching it, and we do not pass that information to anyone else. A natural person running a business may, however, ask us whether their number is being watched, under the right of access to their data (privacy policy, section 8).

Where does the data in the notifications come from?

Solely from the VAT White List maintained by the Polish Ministry of Finance, queried through its official API. To detect a change at all we store the last known state of every watched number — but we do not build a copy of the whole register. We delete the stored state of a number once nobody is watching it. Its change history is kept for up to 90 days.

How often do you check contractors?

Once a day, at 06:00 UTC — that is 07:00 in Polish winter time and 08:00 in summer time. The register itself is updated on business days, so querying more often would not surface anything new. This is not real-time monitoring: up to a day can pass between an actual change in the register and your notification, and when the Ministry of Finance API daily quota runs out, some numbers are checked the following day instead.

When will I get my first notification?

Usually a day after you confirm the sign-up. If the number is new to us, on the first check we record its starting state and deliberately send nothing — there is nothing to compare against yet. If somebody else already watches that number, a notification can arrive at the very next check at 06:00 UTC. Confirm as soon as the message arrives: changes detected before you confirm are not sent retroactively.

What exactly do I get when a contractor changes their bank account?

An e-mail with the tax ID, the entity name as it appears in the register (no name for natural persons running a business), whether the account was added or removed, the masked account number in the form “12…3456” and the date we checked the register. The full account number and the exact detection date are delivered only through technical channels — in the API response, in the MCP tools and in the webhook call (since 26 Sep 2026, for natural persons running a business, only the masked number there too). An account you pay regularly disappearing is a signal to confirm the current number in the account verification tool before your next transfer and to keep the confirmation identifier. Discuss the tax consequences of a specific payment with your accountant.

How is this different from checking the White List by hand?

A manual check shows the state today, but it requires remembering to do it for every contractor and every payment. Monitoring compares the state from one day to the next and speaks up only when something genuinely changed, so you do not have to query the register just in case. It does not replace verifying the account on the day of the transfer — that is what produces a confirmation identifier, which an alert does not.

How do I unsubscribe, and how do I stop watching a single tax ID?

Every notification has an unsubscribe link in its footer: it opens a page where you confirm with a single button. We then delete all your watches, your API key and webhook settings at once and add your address to a suppression list — that does not block signing up again if you ever want to come back. Mail clients supporting the List-Unsubscribe header let you unsubscribe in one click, without opening the page. You can end the watch of a number at any time through the API, with POST /api/unobserve, or with the MCP tool unobserve_nip — we then stop checking it and send no notifications about it. We delete the watch right away — the number doesn't stay on your list. You can also write to info@skanfirmy.pl.

Does monitoring work for sole traders?

Yes, in a narrower scope: for natural persons running a business (tax IDs without a KRS number) we watch only the VAT status and bank accounts (masked); we neither store nor send the name or town (GDPR). You may also be watched by your own contractors — that is a normal part of their verification.

How much does it cost?

Nothing. Signing up needs no payment details, and there is no price list and no paid tier. The section “Scope of the service and limits” above covers what you get and where the limits are. Larger lists and integrations with accounting systems are arranged individually: write to info@skanfirmy.pl.

Will my e-mail address be shared with anyone?

No. The address is used only to deliver the notifications you asked for and to handle sign-up and unsubscribe — we do not sell it, trade it or send offers to it. Besides the address we keep, as proof of consent, the date and IP address of the confirmation and of later requests made through the form (for 3 years after you unsubscribe), and a log of sent notifications (up to 90 days). We use Brevo (Sendinblue SAS, France) to deliver mail and keep the database in Cloudflare D1 in the European Union; both act solely on our instructions. Section 6 of the privacy policy has the details.

← All tools