API Wykazu VAT (Biała Lista) po NIP
REST/JSON bez klucza
Status VAT i dane podmiotu z Wykazu VAT (Biała Lista, Ministerstwo Finansów) po numerze NIP — jednym zapytaniem GET, w odpowiedzi czysty JSON. Bez klucza API i bez rejestracji. Nie mamy własnego limitu dziennego, ale ma go API Ministerstwa Finansów — po jego wyczerpaniu endpoint zwraca 503. To warstwa nad API Wykazu VAT MF, która zdejmuje z Ciebie sesje, daty w URL i parsowanie odpowiedzi.
Jeden GET, jeden JSON
Endpoint jest publiczny, metoda GET, a parametr ?format=json zwraca dane maszynowo (bez niego dostajesz stronę HTML dla człowieka). Dane z Wykazu VAT są w polu bl (Biała Lista):
curl "https://skanfirmy.pl/nip/5260250995?format=json"
W odpowiedzi dostajesz status VAT, oficjalną nazwę, REGON, adres (dla osób fizycznych od 26.09.2026 zamiast adresu sama miejscowość, a od 27.09.2026 bez REGON), numer KRS i znacznik czasu z Ministerstwa Finansów — prosto z Wykazu VAT:
{
"nip": "5260250995",
"source": "krs",
"bl": {
"nip": "5260250995",
"name": "ORANGE POLSKA SPÓŁKA AKCYJNA",
"regon": "012100784",
"statusVat": "Czynny",
"vatActive": true,
"statusVatCode": "active",
"address": "ALEJE JEROZOLIMSKIE 160, 02-326 WARSZAWA",
"krs": "0000010681",
"registrationLegalDate": "1996-01-01",
"accountNumbers": ["<26 cyfr rachunku>", "…"],
"mfRequestDateTime": "25-08-2026 14:59:57"
},
"krs": { ... },
"krsError": null,
"ceidg": null,
"privacy": null,
"checkedAt": "2026-08-25"
}
Bez klucza API i bez rejestracji
Endpoint działa od razu — nie musisz zakładać konta ani generować klucza API. To celowa różnica względem komercyjnych nakładek na Wykaz VAT: chcemy, żeby weryfikację statusu VAT dało się wpiąć w minutę, także z poziomu agenta AI. Limit chroni serwis przed nadużyciami: najwyżej 20 zapytań na 10 sekund z jednego adresu IP (po przekroczeniu kod 429 przez 10 sekund; od 25.09.2026). Nie mamy własnego limitu dziennego, ale ma go API Ministerstwa Finansów dla tego serwisu — po jego wyczerpaniu endpoint zwraca 503 z nagłówkiem Retry-After. Serwis jest bezpłatny i służy do pojedynczych zapytań inicjowanych przez użytkowników lub ich agentów, nie do masowego pobierania danych.
Co zwraca pole bl
Wykaz VAT (Biała Lista) prowadzi Ministerstwo Finansów. Pole bl w odpowiedzi /nip/{nip} zawiera dane podatnika VAT po NIP:
| Pole | Znaczenie |
|---|---|
statusVat | Surowy literał MF, verbatim: Czynny — czynny podatnik VAT, Zwolniony — podatnik zwolniony, Niezarejestrowany — brak w rejestrze VAT |
vatActive | Pole pochodne (boolean): true tylko dla czynnego podatnika VAT (statusVat === "Czynny"). Jednoznaczne, językowo-neutralne rozgałęzienie bez znajomości polskich literałów |
statusVatCode | Pole pochodne (enum): active / exempt / not_registered — maszynowy odpowiednik statusVat, niezależny od języka |
name | Oficjalna nazwa podatnika z Wykazu VAT |
regon | Numer REGON podmiotu; dla osoby fizycznej od 27.09.2026 pole pominięte (w privacy.hidden: regon) |
address | Adres z Wykazu VAT (siedziba lub stałe miejsce prowadzenia działalności). Dla osoby fizycznej od 26.09.2026 zawsze null — zamiast adresu jest miejscowość w city |
city | Tylko osoby fizyczne, od 26.09.2026: sama miejscowość z adresu z Wykazu, podawana zamiast adresu (pomijana, gdy adres nie ma kodu pocztowego) |
krs | Numer KRS (jeśli podmiot jest w Krajowym Rejestrze Sądowym) |
registrationLegalDate | Data rejestracji jako podatnik VAT; dla osoby fizycznej od 27.09.2026 pole pominięte |
accountNumbers | Rachunki bankowe z Białej Listy (NRB, po 26 cyfr) — od 26.09.2026 tylko dla podmiotów z numerem KRS |
accountCount, accountCheck | Tylko osoby fizyczne, od 26.09.2026: liczba rachunków na Białej Liście i — gdy rachunki są — gotowe zapytanie POST /rachunek do sprawdzenia konkretnego numeru |
mfRequestDateTime | Znacznik czasu odpowiedzi Ministerstwa Finansów — dowód, na jaki moment aktualny jest status (przydatne do celów dowodowych) |
Surowy literał MF (statusVat) zostaje w odpowiedzi zawsze i verbatim — to on jest wartością dowodową „co powiedział rejestr". Do rozgałęzień w kodzie użyj pochodnego statusVatCode (active/exempt/not_registered) lub vatActive, albo porównaj do surowego literału ("Czynny", "Zwolniony") — nigdy do przetłumaczonej etykiety wyświetlanej, bo tłumaczenie zmieniłoby wartość, na której opierasz logikę.
Rachunki bankowe z Białej Listy
Dla podmiotów z numerem KRS (spółek, fundacji, stowarzyszeń) endpoint /nip/{nip} zwraca rachunki bankowe zgłoszone na Białej Liście MF — w polu bl.accountNumbers (tablica numerów NRB, po 26 cyfr). Dla osób fizycznych prowadzących działalność od 26.09.2026 zamiast listy podajemy tylko liczbę rachunków (szczegóły niżej). Jeśli chcesz potwierdzić, czy konkretny rachunek figuruje na Wykazie dla danego NIP (należyta staranność), użyj POST /rachunek, narzędzia MCP sprawdz_rachunek albo narzędzia Weryfikacja rachunku — zwracają jednoznaczne „tak/nie" dla pojedynczego rachunku względem Wykazu VAT.
Osoby fizyczne prowadzące działalność — zmiana od 26.09.2026
Podmiot bez numeru KRS — jednoosobową działalność albo spółkę cywilną — traktujemy jak osobę fizyczną, bo jego nazwa, adres i numery rachunków to zwykle dane osobowe przedsiębiorcy lub wspólników. Dlatego od 26.09.2026 zwracamy dla takiego podmiotu tylko to, co potrzebne do sprawdzenia kontrahenta (RODO, zasada minimalizacji danych):
- zamiast listy rachunków — ich liczbę w
bl.accountCount, a gdy rachunki są, takżebl.accountCheck: gotowe zapytaniePOST /rachunekdo sprawdzenia numeru z faktury; - z adresu tylko miejscowość w
bl.city(bl.addressma wartośćnull) — Wykaz nie mówi, czy adres osoby fizycznej to miejsce działalności, czy zamieszkania (art. 96b ust. 3 pkt 7 ustawy o VAT: stałe miejsce działalności, a gdy go nie ma — adres zamieszkania); - od 27.09.2026 bez numeru REGON, daty rejestracji i kodów PKD: pola
bl.regonibl.registrationLegalDatesą pominięte, aceidgma zawsze wartośćnull(PKD osób fizycznych nie pobieramy); - pole
privacy: co pominęliśmy (hidden), dlaczego (reason) i gdzie jest pełny wpis (officialSource— strona Wykazu podatników VAT na gov.pl); - nagłówki
X-Robots-Tag: noindexiCache-Control: private, max-age=3600; strona HTML pokazuje nazwę tylko w treści, bez niej w tytule, opisie i danych strukturalnych.
Dla podmiotów z KRS nic się nie zmienia, a privacy ma wartość null. Tak samo działają /nips/{lista} i narzędzia MCP, a od 27.09.2026 także narzędzia na stronie (Biała Lista VAT, KRS, Bulk NIP i wyszukiwarka na stronie głównej). Fragment odpowiedzi dla osoby fizycznej:
{
"nip": "<NIP>",
"bl": {
"name": "<imię, nazwisko i firma>",
"statusVat": "Czynny",
"address": null,
"city": "WARSZAWA",
"accountCount": 2,
"accountCheck": {
"method": "POST",
"url": "https://skanfirmy.pl/rachunek",
"body": { "nip": "<NIP>", "nrb": "<26 cyfr rachunku>" }
},
...
},
"privacy": {
"naturalPerson": true,
"hidden": ["accountNumbers", "residenceAddress", "regon", "registrationLegalDate"],
"reason": "Dane osoby fizycznej prowadzącej działalność ograniczone do niezbędnych do weryfikacji kontrahenta (RODO). Pełny wpis publikuje rejestr źródłowy (officialSource).",
"officialSource": "https://www.gov.pl/web/kas/wykaz-podatnikow-vat"
},
...
}
Sprawdzenie konkretnego rachunku — POST /rachunek
Od 26.09.2026 numer rachunku z faktury sprawdzisz jednym zapytaniem POST, też bez klucza API. NIP i numer rachunku wysyłasz w treści żądania (JSON), nie w adresie URL — ścieżki URL trafiają do statystyk ruchu, a treść żądania nie:
curl -X POST "https://skanfirmy.pl/rachunek" \
-H "Content-Type: application/json" \
-d '{"nip": "<NIP>", "nrb": "<26 cyfr rachunku>"}'
Pytamy Ministerstwo Finansów (metoda „check" API Wykazu) i zwracamy jego odpowiedź: surowy literał accountAssigned ("TAK" albo "NIE"), pochodne pole assigned (true/false) oraz requestId — identyfikator zapytania z MF, który warto zachować jako dowód należytej staranności:
{
"nip": "<NIP>",
"nrb": "<26 cyfr rachunku>",
"accountAssigned": "TAK",
"assigned": true,
"requestId": "<identyfikator zapytania MF>",
"mfRequestDateTime": "26-09-2026 10:15:02",
"checkedAt": "2026-09-26"
}
Numer rachunku może zawierać spacje i prefiks PL. Błędny NIP albo numer rachunku (długość, suma kontrolna) zwraca 400 bez zapytania do MF, a wyczerpany dzienny limit zapytań MF dla serwisu (albo odmowa MF) — 503 z nagłówkiem Retry-After; od 27.09.2026 taka odpowiedź ma też pole contact z adresem dla integracji, które potrzebują stałego dostępu na większą skalę. Odpowiedzi mają nagłówek Cache-Control: no-store, więc nie są zapisywane w pamięci podręcznej. Obowiązuje ten sam limit co przy pozostałych endpointach: 20 zapytań na 10 sekund z jednego adresu IP. Agent AI zrobi to samo narzędziem MCP sprawdz_rachunek.
W Pythonie
Z biblioteką requests całość to kilka linii. Zwróć uwagę na porównanie do surowego literału "Czynny":
import requests
def status_vat(nip: str) -> str:
r = requests.get(f"https://skanfirmy.pl/nip/{nip}?format=json", timeout=10)
r.raise_for_status()
return r.json()["bl"]["statusVat"]
s = status_vat("5260250995")
# porównuj do surowego literału MF, nie do przetłumaczonej etykiety
if s == "Czynny":
print("Czynny podatnik VAT")
else:
print("Uwaga — status:", s)
# ORANGE POLSKA SPÓŁKA AKCYJNA → Czynny
Podmiot spoza rejestru zwraca 404, a NIP z błędną sumą kontrolną — 400. Warto obsłużyć oba przypadki, zamiast zakładać, że każdy NIP ma wpis.
W JavaScripcie
const r = await fetch("https://skanfirmy.pl/nip/5260250995?format=json");
if (r.ok) {
const { bl } = await r.json();
console.log(bl.name, "→", bl.statusVat);
// bl.statusVat === "Czynny" — porównuj do surowego literału
}
W PHP
$ch = curl_init("https://skanfirmy.pl/nip/5260250995?format=json");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$bl = json_decode(curl_exec($ch), true)["bl"];
echo $bl["name"] . " · VAT: " . $bl["statusVat"];
// ORANGE POLSKA SPÓŁKA AKCYJNA · VAT: Czynny
Wiele NIP-ów naraz
Do sprawdzenia statusu VAT dla listy podmiotów jednym zapytaniem użyj /nips/{lista}?format=json — NIP-y rozdzielasz przecinkami (najwyżej 30 w jednym zapytaniu), a w odpowiedzi dostajesz tablicę results z płaskim wpisem dla każdego z nich (powtórzony NIP liczy się raz, a NIP-y z błędną sumą kontrolną trafiają do invalidInput, nie do results) — bez pola bl i bez odpisu z KRS (pole krs to sam numer z Wykazu): nip, found, name, statusVat (z pochodnymi vatActive i statusVatCode), regon, krs, address, accountNumbers i registrationLegalDate. Dla osób fizycznych (od 27.09.2026 bez regon i registrationLegalDate) address ma wartość null, miejscowość (gdy da się ją odczytać) jest w city, a zamiast accountNumbers są accountCount, privacy i — gdy są rachunki — accountCheck. NIP spoza Wykazu ma tylko nip i found: false:
curl "https://skanfirmy.pl/nips/5260250995,7740001454?format=json"
Więcej niż status VAT — jednym NIP-em
Odpowiedź /nip/{nip}?format=json łączy Wykaz VAT (pole bl) z danymi z KRS (pole krs) w jednej odpowiedzi. Jeśli potrzebujesz też danych z REGON albo walidacji unijnego numeru VAT, użyj osobnych endpointów (wszystkie GET → JSON, bez klucza):
/nip/{nip}— status VAT (Wykaz VAT) + KRS + REGON (poza osobami fizycznymi)/nips/{lista}— wiele NIP-ów naraz (rozdzielonych przecinkami)/regon/{nip}— dane z rejestru REGON (GUS) — zobacz API GUS (REGON)/vies/{kraj}/{numer}— walidacja unijnego numeru VAT (VIES, Komisja Europejska) — zobacz API VIES
Dane z KRS wyciągane po tym samym NIP-ie opisuje API KRS, a dane z REGON — API GUS (REGON).
Dla agentów AI pod adresem https://skanfirmy.pl/mcp stoi serwer Model Context Protocol (MCP) z narzędziem sprawdz_nip (te same dane, w tym pole bl) oraz sprawdz_rachunek (weryfikacja konkretnego rachunku bankowego względem Wykazu VAT) — również bez klucza. Mapa endpointów dla modeli jest w llms.txt, a pełna specyfikacja maszynowa w OpenAPI 3.1. Weryfikację po NIP w interfejsie zrobisz w narzędziu Biała Lista VAT.
Publiczny endpoint a typowe płatne API Wykazu VAT
Większość komercyjnych nakładek REST na Wykaz VAT działa w modelu freemium — konto, klucz API i dzienny limit zapytań w bezpłatnym progu. Ten endpoint jest publiczny i bez opłat. Różnice w skrócie:
| Typowe płatne API Wykazu VAT | skanfirmy.pl /nip | |
|---|---|---|
| Klucz API | wymagany | niepotrzebny |
| Rejestracja / konto | tak | nie |
| Limit zapytań | zwykle jest | 20 zapytań na 10 s z jednego IP; bez własnego limitu dziennego (dzienny limit API MF — po jego wyczerpaniu 503) |
| Format odpowiedzi | REST/JSON | REST/JSON |
| Serwer MCP dla agentów AI | zwykle brak | tak |
| Zakres | zwykle sam status VAT | VAT + KRS + REGON + VIES (osobne endpointy) |
| Model | freemium / abonament | bezpłatnie |
To nie jest oficjalne API Wykazu VAT — dane pochodzą z tego samego źródła (Wykaz VAT prowadzony przez Ministerstwo Finansów), tylko udostępnione jednym zapytaniem GET.
Skąd pochodzą dane i czym to nie jest
Dane pochodzą wprost z Wykazu VAT (Biała Lista) prowadzonego przez Ministerstwo Finansów. To niezależne narzędzie — nie jest oficjalnym API MF ani z nim powiązane; jedynie udostępnia jego dane w wygodniejszej formie. Zakres i aktualność danych są takie, jak w Wykazie VAT; znacznik mfRequestDateTime mówi, na jaki moment status został pobrany z MF.
Najczęstsze pytania
Jak sprawdzić status VAT firmy po NIP w formacie JSON?
Wyślij GET na https://skanfirmy.pl/nip/{NIP}?format=json i odczytaj pole bl.statusVat. Zwraca ono literał Ministerstwa Finansów: Czynny, Zwolniony lub Niezarejestrowany. W tym samym polu bl dostajesz też nazwę, REGON, adres (dla osób fizycznych od 26.09.2026 zamiast adresu sama miejscowość, a od 27.09.2026 bez REGON) i numer KRS.
Czy potrzebny jest klucz API albo rejestracja?
Nie. Endpoint /nip/{nip} jest publiczny — zwraca JSON po dodaniu ?format=json, bez klucza API i bez zakładania konta. Nie mamy własnego limitu dziennego, ale ma go API Ministerstwa Finansów — po jego wyczerpaniu endpoint zwraca 503.
Czy endpoint zwraca listę rachunków bankowych z Białej Listy?
Dla podmiotów z numerem KRS — tak: pole bl.accountNumbers zawiera rachunki (NRB) zgłoszone na Białej Liście. Dla osób fizycznych prowadzących działalność od 26.09.2026 zwracamy tylko liczbę rachunków (bl.accountCount). Żeby jednoznacznie potwierdzić, czy konkretny rachunek figuruje na Wykazie, użyj POST /rachunek, narzędzia MCP sprawdz_rachunek lub narzędzia Weryfikacja rachunku w interfejsie.
Jakie wartości przyjmuje statusVat i jak je porównywać?
Pole statusVat przyjmuje surowe literały Ministerstwa Finansów: Czynny, Zwolniony lub Niezarejestrowany, i zawsze zostaje zachowane verbatim. Do rozgałęzień możesz użyć pochodnego enuma statusVatCode (active/exempt/not_registered) albo boolean vatActive, oba niezależne od języka; jeśli porównujesz do surowego literału, nie tłumacz go przed rozgałęzieniem — tłumaczenie zmieniłoby wartość, na której opiera się logika.
Czy korzystanie jest płatne?
Nie. Endpoint jest bezpłatny i bez rejestracji. Dane pochodzą wprost z Wykazu VAT (Biała Lista) prowadzonego przez Ministerstwo Finansów.