API Białej listy VAT: nowy adres i migracja przed 1.12.2026
Nowy adres API wykazu podatników VAT od 15.10.2026, stary wl-api.mf.gov.pl do 1.12.2026. Endpointy, limity, kody błędów, kod migracji i plik płaski.
Krótka odpowiedź
Od 15.10.2026 API Białej listy VAT działa pod adresem https://wykazpodatnikowvat.mf.gov.pl/api/, a stary https://wl-api.mf.gov.pl Ministerstwo Finansów obsługuje do 1.12.2026. W kodzie zmieniasz host: ścieżki /api/search/... i /api/check/..., parametr date i format JSON się nie zmieniły, a API dalej nie wymaga klucza. Zmienił się też certyfikat TLS.
Sprawdziliśmy to 1 listopada 2026 czternastoma zapytaniami do produkcyjnego i testowego API oraz odczytem certyfikatów obu hostów. Ten przewodnik jest dla każdego, kto ma Białą listę wpiętą w ERP, program księgowy, system płatności albo własny skrypt. Sami przestawiliśmy adres 29.10.2026: u nas zmiana objęła jedną stałą z adresem, komentarze i trzy testy, które sprawdzały adres literalnie. Szerszy przegląd rejestrów firm (REGON, CEIDG, KRS) znajdziesz we wpisie ile firm jest w Polsce.
Co dokładnie zmienia się w API Białej listy?
Komunikat MF jest na stronie API Wykazu podatników VAT na gov.pl (wersja strony 30.0 z 15.10.2026, odczyt 1.11.2026 ok. 19:00). MF pisze, że 15.10.2026 usługa wl-api.mf.gov.pl zostanie przekierowana do nowej witryny, a dotychczasowy adres będzie obsługiwany do 1.12.2026. Dodaje też: „W związku z migracją zmieniony zostanie również certyfikat bezpieczeństwa witryny”. Uwaga: ta sama strona nadal pokazuje stare adresy (wl-test i wl-api) nad blokiem „Adresy ważne od 15 października 2026”, więc kopiując adres, bierz go z tego bloku.
| Element | Stary adres | Nowy adres (od 15.10.2026) | Co widzieliśmy 1.11.2026 |
|---|---|---|---|
| API produkcyjne | https://wl-api.mf.gov.pl | https://wykazpodatnikowvat.mf.gov.pl/api/ | oba hosty zwracają te same dane, HTTP 200 |
| API testowe | https://wl-test.mf.gov.pl | https://wykazpodatnikowvat-test.mf.gov.pl/api/ | obie strony startowe odpowiadają, nowe testowe zwraca dane testowe |
| API WL2 (status VAT) | brak w komunikacie | https://wykazpodatnikowvat.mf.gov.pl/api2, test: https://wykazpodatnikowvat-test.mf.gov.pl/api2 | działa, date opcjonalny |
| Plik płaski | https://plikplaski.mf.gov.pl/pliki//RRRRMMDD.7z | https://wykazpodatnikowvat.mf.gov.pl/plikplaski/RRRRMMDD.7z | stary adres zwraca 301 na nowy |
| Certyfikat TLS | CN=wl-api.mf.gov.pl, ważny do 6.03.2027 | CN=*.mf.gov.pl, ważny do 18.12.2026 | ten sam wystawca: GeoTrust TLS RSA CA G1 (DigiCert) |
Ważny szczegół z pomiaru: 1.11.2026 stary host nie przekierowywał zapytań kodem 301 ani 302, tylko odpowiadał sam (HTTP 200) tymi samymi danymi co nowy. Integracja na starym adresie działa więc dziś bez błędu i nic nie sygnalizuje problemu. MF nie napisał, co stanie się z wl-api.mf.gov.pl po 1.12.2026, więc nie zakładaj, że przekierowanie zrobi pracę za Ciebie.
Checklista migracji przed 1 grudnia 2026
- Znajdź wszystkie wystąpienia starych adresów. Szukaj w kodzie, plikach konfiguracyjnych, ustawieniach ERP, kolekcjach Postmana, cronach i testach:
grep -rn "wl-api.mf.gov.pl\|wl-test.mf.gov.pl\|plikplaski.mf.gov.pl" . - Uważaj na podwójne
/api. Kontrakt Swagger ma ścieżki zaczynające się od/api/...i/api2/..., a MF podaje adres produkcyjny już z/api/na końcu. Jeśli Twój kod dokleja/api/search/...do bazy, baza tohttps://wykazpodatnikowvat.mf.gov.pl, bez/api. Inaczej wyślesz zapytanie na/api/api/search/.... - Sprawdź certyfikat i przypinanie. Jeśli przypinasz certyfikat albo klucz publiczny (pinning w aplikacji mobilnej, w kliencie .NET albo w Javie z własnym truststore), stary odcisk nie pasuje do nowego hosta. Certyfikat
*.mf.gov.plz 1.11.2026 jest ważny do 18.12.2026, więc przypięcie konkretnego certyfikatu zepsuje się znowu za kilka tygodni. Bezpieczniej weryfikować łańcuch do urzędu certyfikacji: 1.11.2026 był to GeoTrust TLS RSA CA G1, a nad nim DigiCert Global Root G2. Własny truststore musi zawierać ten łańcuch. - Dopisz domenę do reguł ruchu wychodzącego. Firewall, proxy firmowe albo allowlista w chmurze, które przepuszczały tylko
wl-api.mf.gov.pl, zablokują nowy host. - Popraw testy i mocki. Testy, które sprawdzają literalny adres, przejdą na starym adresie aż do dnia wyłączenia. U nas były to trzy testy.
- Zmień adres pliku płaskiego. Stary adres zwraca 301 z pustą treścią (
Content-Length: 0). Skrypt bez śledzenia przekierowań, na przykładcurlbez-L, zapisze pusty plik i rozpakowanie się nie uda. - Rozważ API WL2. Jeśli potrzebujesz tylko statusu VAT po NIP, nowa usługa
/api2/status/nip/{nip}ma limit 50 000 zapytań dziennie, czyli wyraźnie więcej niżsearch. - Loguj
requestIdi kod błędu. Bez tego nie odróżnisz przekroczenia limitu od złego NIP-u ani nie udokumentujesz sprawdzenia. - Przetestuj przed 1.12.2026 i usuń stary adres z konfiguracji. Zostaw na kilka dni alarm na każde wywołanie starego hosta w logach albo w DNS, żeby wyłapać zapomniany skrypt.
Jakie endpointy ma API wykazu podatników VAT?
Według opisu API w wersji 1.6.1 z 12.10.2026 usługa nie wymaga uwierzytelniania i pozwala szukać po NIP, REGON i numerze rachunku na wskazany dzień, do 5 lat wstecz. Metody search zwracają pełny zakres danych, a metody check tylko odpowiedź, czy rachunek jest przypisany do podmiotu czynnego. Ścieżki poniżej pochodzą z kontraktu Swagger v1.6.1; dopisujesz je do bazy https://wykazpodatnikowvat.mf.gov.pl.
| Ścieżka (GET) | Co zwraca | Limit, z którego korzysta |
|---|---|---|
/api/search/nip/{nip}?date=RRRR-MM-DD | jeden podmiot, pełne dane, requestId | search |
/api/search/nips/{nip1,nip2,...}?date=... | do 30 podmiotów w jednym zapytaniu | search |
/api/search/regon/{regon}?date=... | jeden podmiot (REGON 9 lub 14 cyfr) | search |
/api/search/regons/{regony}?date=... | do 30 podmiotów | search |
/api/search/bank-account/{rachunek}?date=... | lista podmiotów z tym rachunkiem | search |
/api/search/bank-accounts/{rachunki}?date=... | do 30 rachunków | search |
/api/check/nip/{nip}/bank-account/{rachunek}?date=... | accountAssigned: TAK albo NIE | check |
/api/check/regon/{regon}/bank-account/{rachunek}?date=... | accountAssigned: TAK albo NIE | check |
/api2/status/nip/{nip}?date=... | sam status VAT, data, requestId | WL2 |
Parametr date jest wymagany we wszystkich ścieżkach /api/..., a w /api2/... jest opcjonalny: bez niego WL2 odpowiada na dziś. Datę wysyłasz jako RRRR-MM-DD. Uważaj na pole requestDateTime w odpowiedzi: ma inny format, DD-MM-RRRR GG:MM:SS (np. 01-11-2026 19:01:42), więc nie parsuj go tą samą funkcją.
Pełna odpowiedź search zawiera m.in. name, nip, statusVat (wartości Czynny, Zwolniony, Niezarejestrowany), regon, krs, workingAddress, residenceAddress, daty registrationLegalDate, registrationDenialDate, removalDate, restorationDate, pole exemptionSmeDate (dodane w wersji 1.6.0), listę accountNumbers w formacie NRB (26 cyfr) i znacznik hasVirtualAccounts. Są tam też representatives, authorizedClerks i partners z imionami, nazwiskami i numerami identyfikacyjnymi osób. To dane osobowe, więc zapisuj tylko pola, których potrzebujesz. Jak często te pola są w ogóle wypełnione, sprawdziliśmy w osobnym pomiarze we wpisie o osobach decyzyjnych w firmie.
Tak wyglądała skrócona odpowiedź z nowego hosta 1.11.2026 (pominęliśmy pola z osobami i adresy, a 236 numerów rachunków zastąpiliśmy opisem):
{ "result": { "subject": { "name": "ORLEN SPÓŁKA AKCYJNA", "nip": "7740001454", "statusVat": "Czynny", "regon": "610188201", "krs": "0000028860", "registrationLegalDate": "1993-07-05", "removalDate": null, "exemptionSmeDate": null, "accountNumbers": ["(236 numerów NRB)"], "hasVirtualAccounts": true }, "requestDateTime": "01-11-2026 19:01:42", "requestId": "nWMr1-995m4g6" } }
Ile zapytań dziennie przyjmuje API Białej listy?
Limity podaje strona MF o API (odczyt 1.11.2026). Plik płaski opisuje specyfikacja techniczna.
| Usługa | Limit | Uwagi |
|---|---|---|
search | 100 zapytań dziennie, każde o maks. 30 podmiotów | zapytaniem grupowym sprawdzisz do 3 000 podmiotów na dobę |
check | 5 000 podmiotów | odpowiedź TAK albo NIE |
WL2 (/api2) | 50 000 zapytań na dzień | tylko status VAT po NIP |
| Plik płaski | bez limitu pobrań | dane z dnia wygenerowania pliku |
Po wyczerpaniu jednego z limitów dostęp może zostać zablokowany do godziny 0:00, a blokada obejmuje search, check i wyszukiwarkę na stronie wykazu. MF zaznacza, że blokowanie jest fakultatywne i że osobne zabezpieczenia reagują na zbyt szybkie odpytywanie, ale ich szczegółów nie publikuje. Strona z limitami nie mówi, czy limit liczy się na adres IP. Mówi to natomiast lista kodów błędów: kod WL-191 (HTTP 429) brzmi „Limit żądań dla tego adresu IP został na dziś wyczerpany”. W praktyce systemy wychodzące do internetu z jednego adresu (biuro za NAT-em, wspólny serwer) dzielą jeden limit.
U nas limit MF to 100 zapytań search na dobę, a nasze progi są niższe, osobne dla zapytań interaktywnych i dla zadań w tle (90 i 70). Po odpowiedzi 429 albo 403 nie pytamy MF przez 30 minut, a wynik dla spółki z numerem KRS trzymamy w pamięci podręcznej 24 godziny. To nasza decyzja inżynierska, nie wymóg MF, ale pokazuje zasadę: licz zapytania sam, zanim policzy je MF.
Przykłady migracji: curl, JavaScript i Python
Zasada jest jedna: adres API trzymaj w konfiguracji (zmienna środowiskowa, plik ustawień, parametr w ERP), a nie w kodzie. Następna zmiana adresu to wtedy zmiana jednej wartości bez wdrożenia. Druga zasada: datę licz w strefie Europe/Warsaw. Serwer w UTC tuż po północy czasu polskiego wyśle wczorajszą datę, a serwer w strefie przed Polską wyśle jutrzejszą i dostanie błąd WL-103.
Trzy wywołania poniżej to kolejno: status VAT z requestId (limit search), sprawdzenie rachunku (limit check) i sam status przez WL2 (limit 50 000 dziennie). Przed migracją ten sam kod miał bazę https://wl-api.mf.gov.pl.
export WL_API_BASE="https://wykazpodatnikowvat.mf.gov.pl" DATA=$(TZ=Europe/Warsaw date +%F) curl -s "$WL_API_BASE/api/search/nip/7740001454?date=$DATA" \ | jq '{status: .result.subject.statusVat, requestId: .result.requestId}' curl -s "$WL_API_BASE/api/check/nip/7740001454/bank-account/NUMER_NRB_26_CYFR?date=$DATA" | jq . curl -s "$WL_API_BASE/api2/status/nip/7740001454" | jq .
W JavaScript (Node 18 lub nowszy, wbudowany fetch) warto sprawdzić sumę kontrolną NIP przed zapytaniem: zły numer i tak skończy się błędem WL-115, a nie ma powodu zużywać na niego limitu.
const WL_API_BASE = process.env.WL_API_BASE ?? "https://wykazpodatnikowvat.mf.gov.pl" const dzisWarszawa = () => new Intl.DateTimeFormat("sv-SE", { timeZone: "Europe/Warsaw" }).format(new Date()) // RRRR-MM-DD function poprawnyNip(nip) { if (!/^\d{10}$/.test(nip)) return false const wagi = [6, 5, 7, 2, 3, 4, 5, 6, 7] const suma = wagi.reduce((s, w, i) => s + w * Number(nip[i]), 0) return suma % 11 === Number(nip[9]) } export async function sprawdzNip(nipWejscie, data = dzisWarszawa()) { const nip = String(nipWejscie).replace(/\D/g, "") // "PL 774-000-14-54" -> "7740001454" if (!poprawnyNip(nip)) throw new Error("Zły NIP, zapytanie nie zostało wysłane") const res = await fetch(`${WL_API_BASE}/api/search/nip/${nip}?date=${data}`, { headers: { Accept: "application/json" }, signal: AbortSignal.timeout(10_000), }) const body = await res.json().catch(() => null) if (!res.ok) { // Czytaj kod WL, a nie tylko status HTTP: aktualizacja bazy (WL-196) też przychodzi jako 400 throw Object.assign(new Error(body?.message ?? `HTTP ${res.status}`), { code: body?.code, status: res.status }) } const { subject, requestId, requestDateTime } = body.result return { wWykazie: subject !== null, // brak podmiotu to HTTP 200 i subject: null statusVat: subject?.statusVat ?? null, rachunki: subject?.accountNumbers ?? [], requestId, requestDateTime, } }
W Pythonie to samo dla metody check, z biblioteką requests:
import os import re from datetime import datetime from zoneinfo import ZoneInfo import requests WL_API_BASE = os.environ.get("WL_API_BASE", "https://wykazpodatnikowvat.mf.gov.pl") def dzis_warszawa() -> str: return datetime.now(ZoneInfo("Europe/Warsaw")).strftime("%Y-%m-%d") def sprawdz_rachunek(nip: str, nrb: str, data: str | None = None) -> dict: nip = re.sub(r"\D", "", nip) nrb = re.sub(r"\D", "", nrb) # API chce 26 cyfr NRB, bez "PL" i spacji r = requests.get( f"{WL_API_BASE}/api/check/nip/{nip}/bank-account/{nrb}", params={"date": data or dzis_warszawa()}, headers={"Accept": "application/json"}, timeout=10, ) body = r.json() if r.status_code != 200: raise RuntimeError(f"{body.get('code')}: {body.get('message')}") wynik = body["result"] return { "przypisany": wynik["accountAssigned"] == "TAK", "requestId": wynik["requestId"], "czas_odpowiedzi": wynik["requestDateTime"], }
Jak sprawdzić, że migracja działa?
Zacznij od testu dymnego: jeden znany NIP na obu hostach i porównanie wyniku. W naszym teście 1.11.2026 oba hosty zwróciły dla tej samej spółki status Czynny, 236 rachunków i znacznik rachunków wirtualnych, a każda odpowiedź przyszła w około 0,1 s. Taki test zużywa dwa zapytania search ze stu.
DATA=$(TZ=Europe/Warsaw date +%F) for HOST in https://wl-api.mf.gov.pl https://wykazpodatnikowvat.mf.gov.pl; do curl -s "$HOST/api/search/nip/7740001454?date=$DATA" \ | jq -c --arg host "$HOST" '{host: $host, status: .result.subject.statusVat, rachunki: (.result.subject.accountNumbers | length), requestId: .result.requestId}' done
Obsługę błędów testuj w środowisku testowym https://wykazpodatnikowvat-test.mf.gov.pl/api/, a nie na produkcji. MF publikuje do niego plik z danymi testowymi v1.6.1: listy fikcyjnych NIP-ów, REGON-ów i rachunków. 1.11.2026 pierwszy NIP z tego pliku zwrócił w środowisku testowym fikcyjny podmiot „Nazwa Firmy 1”. Limitów środowiska testowego nie sprawdzaliśmy, a MF ich nie podaje.
Na koniec sprawdź trzy rzeczy, które test dymny pomija: czy klient HTTP przyjmuje nowy certyfikat (w tym na serwerze produkcyjnym, nie tylko na laptopie), czy firewall przepuszcza nowy host i czy skrypt pobierający plik płaski ściąga plik o sensownym rozmiarze, a nie pusty.
Czym jest requestId i kiedy wybrać plik płaski?
requestId to unikalny identyfikator zapytania (w kontrakcie maks. 18 znaków, np. nWMr1-995m4g6). Według opisu API v1.6.1 wszystkie zapytania są zapisywane w bazie MF, a identyfikator może także potwierdzać fakt wykonania zapytania przed organami podatkowymi. Dostajesz go nawet wtedy, gdy podmiotu nie ma w wykazie: 1.11.2026 zapytanie o NIP z poprawną sumą kontrolną, którego nie ma w wykazie, zwróciło HTTP 200, subject: null i requestId. Zapisuj go razem z NIP-em, rachunkiem, datą date i dniem zlecenia przelewu.
Plik płaski to inne narzędzie: codzienny plik do sprawdzania offline. 1.11.2026 plik z tego dnia miał 237 MB (archiwum 7z). Według specyfikacji zawiera dane w formacie JSON, w których data wygenerowania pliku, NIP i numer rachunku są złączone i przepuszczone przez SHA-512 tyle razy, ile podaje nagłówek pliku (w przykładzie ze specyfikacji 5 000 razy). Są w nim dwa bloki, podatnicy czynni i zwolnieni, oraz maski rachunków wirtualnych. Niezarejestrowanych w pliku nie ma. Pobieranie nie ma limitu, a MF udostępnia archiwum z ostatnich 30 dni.
| Sposób | Co sprawdzasz | Limit | Ślad sprawdzenia | Kiedy ma sens |
|---|---|---|---|---|
search | pełne dane podmiotu | 100 zapytań dziennie po 30 podmiotów | requestId | onboarding kontrahenta, pojedyncze sprawdzenia |
check | parę NIP i rachunek | 5 000 podmiotów | requestId | sprawdzenie przed przelewem |
| WL2 | status VAT | 50 000 zapytań dziennie | requestId | masowe sprawdzanie statusu bez rachunków |
| Plik płaski | parę NIP i rachunek w skrócie SHA-512 | bez limitu | brak requestId, zapis prowadzisz sam | tysiące przelewów dziennie, systemy bankowe i ERP |
Szkic liczenia skrótu dla pliku płaskiego w Pythonie (przed użyciem produkcyjnym porównaj wynik z przykładami ze specyfikacji i z liczbą transformacji z nagłówka pliku):
import hashlib def skrot_plik_plaski(data_pliku: str, nip: str, nrb: str = "", transformacje: int = 5000) -> str: wsad = data_pliku.replace("-", "") + nip + nrb # np. "20261101" + NIP + NRB for _ in range(transformacje): wsad = hashlib.sha512(wsad.encode("utf-8")).hexdigest() return wsad
Co mówią przepisy o sprawdzaniu rachunku kontrahenta?
To opis przepisów, nie porada podatkowa. Teksty jednolite sprawdziliśmy w Dzienniku Ustaw 1.11.2026.
- Art. 96b ustawy o VAT (Dz.U. 2026 poz. 1263): Szef KAS prowadzi wykaz i udostępnia go w BIP w sposób umożliwiający sprawdzenie, także automatyczne, na wybrany dzień z okresu 5 lat poprzedzających rok sprawdzania. Wykaz zawiera m.in. numery rachunków rozliczeniowych.
- Art. 19 ustawy Prawo przedsiębiorców (Dz.U. 2025 poz. 1480): płatność idzie przez rachunek płatniczy, gdy stroną transakcji jest inny przedsiębiorca, a jednorazowa wartość transakcji przekracza 15 000 zł. Stąd próg, o którym mowa przy Białej liście.
- Art. 22p ustawy o PIT (Dz.U. 2026 poz. 592) i art. 15d ustawy o CIT (Dz.U. 2026 poz. 554): kosztu nie zalicza się do kosztów uzyskania przychodów w części, w jakiej płatność za taką transakcję poszła przelewem na rachunek inny niż zawarty w wykazie na dzień zlecenia przelewu (gdy dostawca jest czynnym podatnikiem VAT). Przepisy wymieniają wyjątki, m.in. zawiadomienie naczelnika urzędu skarbowego w terminie 7 dni od zlecenia przelewu i zapłatę w mechanizmie podzielonej płatności.
- Art. 117ba Ordynacji podatkowej (Dz.U. 2026 poz. 622): nabywca będący podatnikiem VAT odpowiada solidarnie ze sprzedawcą (czynnym podatnikiem VAT) za jego zaległość w VAT w części przypadającej na daną dostawę, jeśli zapłacił przelewem na rachunek inny niż zawarty w wykazie na dzień zlecenia przelewu. Paragraf 3 wyłącza to m.in. dla transakcji innych niż z art. 19 Prawa przedsiębiorców, przy zawiadomieniu naczelnika urzędu skarbowego w 7 dni i przy zapłacie w mechanizmie podzielonej płatności.
Dla programisty z tych przepisów wynika jedno wymaganie techniczne: liczy się stan wykazu na dzień zlecenia przelewu. Integracja powinna więc pytać z date równym dniowi zlecenia i zapisywać requestId przy płatności. Co zrobić, gdy rachunku nie ma w wykazie, zależy od okoliczności, więc tę decyzję zostaw księgowemu albo doradcy podatkowemu.
Typowe błędy API i jak się przed nimi bronić
Kody pochodzą z listy kodów błędów v1.6.1. Kolumna „Nasz test” pokazuje, co zwróciło produkcyjne API 1.11.2026.
| Kod | HTTP | Znaczenie | Nasz test | Jak się bronić |
|---|---|---|---|---|
WL-101, WL-102 | 400 | brak daty albo zły format | date=01-11-2026 dał WL-102 | wysyłaj RRRR-MM-DD |
WL-103 | 400 | data w przyszłości | date=2026-12-01 dał WL-103 | licz datę w strefie Europe/Warsaw |
WL-118 | 400 | data sprzed zakresu rejestru | date=2019-01-01 dał WL-118 | nie cofaj się dalej niż 5 lat przed bieżącym rokiem |
WL-112 do WL-115 | 400 | NIP pusty, zła długość, niedozwolone znaki, zła suma kontrolna | 774-000-14-54 dał WL-113, 1234567890 dał WL-115 | usuń znaki inne niż cyfry, sprawdź sumę kontrolną przed wysłaniem |
WL-104 do WL-107 | 400 | błędny REGON (9 lub 14 cyfr) | nie testowaliśmy | waliduj długość i cyfry |
WL-108 do WL-111 | 400 | błędny rachunek (26 cyfr) | nie testowaliśmy | wysyłaj NRB, nie IBAN z „PL” |
WL-130 | 400 | za dużo argumentów | nie testowaliśmy | dziel listy na paczki po 30 |
WL-191 | 429 | limit dla adresu IP na dziś wyczerpany | nie wywoływaliśmy | zatrzymaj zapytania do północy, nie ponawiaj w pętli |
WL-195, WL-196 | 400 | baza została zaktualizowana albo trwa aktualizacja | nie wystąpiły | ponów zapytanie po chwili |
WL-100, WL-197 | 500 | błąd serwera, brak statusu historycznego | nie wystąpiły | ponów z rosnącym odstępem |
Dwie pułapki widać dopiero w kodzie. Pierwsza: HTTP 400 nie znaczy „brak podmiotu”. Brak w wykazie to HTTP 200 i subject: null, a 400 przychodzi też przy aktualizacji bazy (WL-195, WL-196), więc decyzję podejmuj po polu code. Druga: w zapytaniu grupowym błędny numer nie psuje całej odpowiedzi. 1.11.2026 zapytanie /api/search/nips/ o trzy NIP-y zwróciło HTTP 200, dwa podmioty i przy trzecim wpisie obiekt error z kodem WL-115. Sprawdzaj więc każdy wpis z osobna.
Gdzie Biała lista ma sens w sprzedaży B2B?
Przed pierwszą fakturą albo umową z nowym kontrahentem sprawdzenie statusu VAT i rachunku zajmuje chwilę, a integracja nie jest do tego potrzebna. Narzędzie Sprawdź NIP robi to w przeglądarce: po wpisaniu NIP-u pokazuje status VAT z wykazu MF z dniem, na który pytano, i godziną odczytu, a dla spółek także dane z KRS (nazwa, forma prawna, siedziba, kapitał, sygnały z odpisu takie jak likwidacja), kody PKD 2007 i 2025, liczbę rachunków z wykazu i stronę WWW wpisaną w KRS; dla jednoosobowej działalności pokazuje wyłącznie status VAT, wynik pamięta do 24 godzin, a jako potwierdzenie do dokumentacji i tak pobierz wynik z wyszukiwarki MF. Jeśli zamiast sprawdzać jedną firmę szukasz listy firm z branży, opisaliśmy źródła na stronach baza firm KRS i baza firm CEIDG, a firmy z branży i miasta (z CEIDG, po PKD) wyszukasz na darmowym koncie.
Najczęstsze pytania
Jaki jest nowy adres API Białej listy?
Produkcyjne API wykazu podatników VAT działa od 15.10.2026 pod adresem https://wykazpodatnikowvat.mf.gov.pl/api/, a testowe pod https://wykazpodatnikowvat-test.mf.gov.pl/api/. Ścieżki są te same co wcześniej, np. /api/search/nip/{nip}?date=RRRR-MM-DD. Nowa usługa WL2 do samego statusu VAT jest pod /api2.
Do kiedy działa stary adres wl-api.mf.gov.pl?
Według komunikatu MF na gov.pl stary adres jest obsługiwany do 1.12.2026. 1.11.2026 nadal odpowiadał bez przekierowania, z tymi samymi danymi co nowy host. MF nie napisał, co stanie się z nim po 1.12.2026, więc przestaw integrację wcześniej.
Czy API Białej listy jest darmowe i wymaga klucza?
Jest bezpłatne i według opisu API v1.6.1 nie wymaga uwierzytelniania, więc nie ma klucza ani rejestracji. Ograniczają je tylko dzienne limity zapytań. Plik płaski też jest bezpłatny i nie ma limitu pobrań.
Jaki jest dzienny limit zapytań do API wykazu podatników VAT?
Metoda search przyjmuje 100 zapytań dziennie, każde o maksymalnie 30 podmiotów, metoda check 5 000 podmiotów, a API WL2 50 000 zapytań dziennie. Po wyczerpaniu limitu dostęp może być zablokowany do północy. Kod błędu WL-191 wskazuje, że limit liczy się dla adresu IP.
Czy poza adresem trzeba coś zmienić w integracji?
Ścieżki, parametry i format JSON zostały takie same, ale zmienił się certyfikat TLS, więc przypięty certyfikat albo własny truststore trzeba zaktualizować. Sprawdź też reguły firewalla dla nowej domeny, testy z literalnym adresem i adres pobierania pliku płaskiego. Uważaj, żeby nie skleić bazy z /api/ i ścieżki z /api/ w podwójne /api/api/.
Czym jest requestId w odpowiedzi API?
To unikalny identyfikator zapytania, który MF zapisuje w swojej bazie. Według opisu API może potwierdzać fakt wykonania zapytania przed organami podatkowymi. API zwraca go także wtedy, gdy podmiotu nie ma w wykazie, więc zapisuj go razem z NIP-em, rachunkiem i datą sprawdzenia.
Jak sprawdzić rachunek kontrahenta przez API?
Wywołaj /api/check/nip/{nip}/bank-account/{rachunek}?date=RRRR-MM-DD z 26-cyfrowym numerem NRB i datą zlecenia przelewu. API odpowie TAK albo NIE w polu accountAssigned oraz zwróci requestId. Pojedyncze sprawdzenie bez kodu zrobisz w wyszukiwarce na wykazpodatnikowvat.mf.gov.pl.
Czym różni się API WL2 od zwykłego API?
WL2 (/api2/status/nip/{nip}) zwraca tylko NIP, status VAT, datę, czas odpowiedzi i requestId, bez nazwy, adresu i rachunków. Ma za to limit 50 000 zapytań dziennie, a parametr date jest w nim opcjonalny. Do sprawdzenia rachunku nadal potrzebujesz metody check albo pliku płaskiego.
Stan na 1 listopada 2026. Dane pochodzą ze strony API Wykazu podatników VAT na gov.pl (odczyt 1.11.2026 ok. 19:00), z dokumentacji API v1.6.1 z 12.10.2026 (opis PDF, kontrakt Swagger, lista kodów błędów, dane testowe), ze strony i specyfikacji pliku płaskiego (plik specyfikacji z 30.09.2026) oraz z tekstów jednolitych ustaw w Dzienniku Ustaw. Pomiar własny: 14 zapytań do produkcyjnego i testowego API, odczyt certyfikatów TLS obu hostów i sprawdzenie nagłówków plików płaskich 1.11.2026 między 19:01 a 19:10.
Wyszukaj firmy z Twojej branży i miasta.
OutreachPilot szuka firm w Google Maps, PKT.pl i CEIDG, pokazuje dostępne dane kontaktowe i od razu przygotowuje kampanię po polsku.
14 dni Pro bez karty · potem Free 0 zł
Podobne artykuły
Biała lista podatników VAT: jak sprawdzić kontrahenta
Jak sprawdzić firmę na białej liście podatników VAT: status czynny lub zwolniony, numer konta, pole „Stan na dzień”, identyfikator wyszukania i próg 15 000 zł.
