A unified, fully typed TypeScript client for Polish company registries: the VAT whitelist ("Biała lista podatników VAT"), VIES (EU VAT number validation), and a roadmap for GUS/REGON.
- Strict TypeScript, ships dual ESM + CJS builds with
.d.ts - Single runtime dependency:
@m8t-jacob/validate, used to validate NIP checksums before any network request is made - Tree-shakeable; import the whole package or a single subpath
- Zero real network calls in tests — the test suite mocks
fetch, so CI runs deterministically offline - Honest about what isn't done yet:
gus.tsis a documented stub, not a fake implementation (see Roadmap below)
npm install @m8t-jacob/polish-registryimport { checkAccount, checkNip, checkVat } from '@m8t-jacob/polish-registry';
await checkNip('5252445767');
// { nip: '5252445767', name: '...', statusVat: 'Czynny', regon: '...', krs: '...', accountNumbers: [...], requestId: '...', found: true }
await checkAccount('10114020040000381203083904', '5252445767'); // true | false
await checkVat('PL', '5252445767');
// { valid: true, name: '...', address: '...', countryCode: 'PL', vatNumber: '5252445767', requestDate: '...' }You can also import from a subpath if you only need one module, which keeps bundlers from pulling in the others:
import { checkNip, checkAccount } from '@m8t-jacob/polish-registry/whitelist';
import { checkVat } from '@m8t-jacob/polish-registry/vies';Or use the PolishRegistry namespace if you prefer a single import:
import { PolishRegistry } from '@m8t-jacob/polish-registry';
await PolishRegistry.whitelist.checkNip('5252445767');
await PolishRegistry.vies.checkVat('PL', '5252445767');Client for the Polish Ministry of Finance's "Biała lista podatników VAT" /
"wykaz podatników VAT" public REST API (https://wl-api.mf.gov.pl, no API
key required).
| Function | Description |
|---|---|
checkNip(nip, options?): Promise<WhitelistResult> |
Looks up a NIP, returning name, VAT status, REGON/KRS, and bank accounts |
checkAccount(account, nip, options?): Promise<boolean> |
Whether a 26-digit bank account (NRB) is registered to a NIP |
options.date (YYYY-MM-DD) queries the registry as of that date; it
defaults to today. Both functions validate the NIP with
isValidNip from @m8t-jacob/validate before making a network call,
throwing RegistryError immediately for an invalid checksum.
interface WhitelistResult {
nip: string;
name: string | null;
statusVat: string | null; // e.g. 'Czynny', 'Zwolniony', or null when not found
regon: string | null;
krs: string | null;
accountNumbers: string[];
requestId: string;
found: boolean;
}Client for the European Commission's VIES (VAT Information Exchange System) public REST API, used to validate EU VAT numbers.
| Function | Description |
|---|---|
checkVat(countryCode, vatNumber): Promise<ViesResult> |
Validates an EU VAT number, returning name/address if available |
EU_COUNTRY_CODES |
The 27 accepted 2-letter codes (EL for Greece) plus XI (Northern Ireland) |
interface ViesResult {
valid: boolean;
name?: string;
address?: string;
countryCode: string;
vatNumber: string;
requestDate: string;
}Endpoint note: this package calls
https://ec.europa.eu/taxation_customs/vies/rest-api/ms/{countryCode}/vat/{vatNumber},
the public REST API that succeeded the older SOAP checkVatService. It was
manually confirmed reachable and returning the { isValid, requestDate, name, address, vatNumber } shape documented above as of 2026-07-13
(the same date this package's country list was cross-checked against the
live GET .../rest-api/check-status endpoint). If the European Commission
changes this endpoint, please open an issue.
| Export | Description |
|---|---|
RegistryError |
Thrown by every client for invalid input, network failures, timeouts, or non-OK API responses; has an optional status |
PolishRegistry |
Convenience namespace: { whitelist, vies, gus } |
Every request has a 10-second timeout (AbortSignal.timeout); a timed-out
or failed request always surfaces as RegistryError, never an unhandled
rejection with a different shape.
getGusReport() is a stub that always throws RegistryError('GUS BIR client not yet implemented — see roadmap'). See Roadmap.
- GUS/REGON (BIR) client. GUS's "Baza Internetowa REGON" web service is
SOAP-based (BIR1.1), requires a registered API key (
sid) from https://api.stat.gov.pl, a stateful login/logout session, periodic keep-alives, and XML parsing of the report payloads embedded in the SOAP envelope. That's meaningfully more surface than the REST/JSON clients above, so it's deliberately left as a documented stub (src/gus.ts) rather than a half-working implementation. Tracked inGOOD_FIRST_ISSUES.md— contributions welcome. - Retry/backoff for transient network failures on the whitelist and VIES clients.
- KRS (Krajowy Rejestr Sądowy) API client, once a stable public REST endpoint is confirmed.
@m8t-jacob/polish-registry to zunifikowany, w pełni typowany klient TS do
polskich rejestrów firmowych: Biała lista podatników VAT (API
Ministerstwa Finansów), VIES (walidacja numerów VAT w UE) oraz
zaślepka GUS/REGON wraz z jawnie opisanym planem (roadmapą) na
przyszłość. Pakiet ma jedną zależność uruchomieniową —
@m8t-jacob/validate — używaną do walidacji sumy kontrolnej NIP przed
wysłaniem jakiegokolwiek zapytania sieciowego. Klient GUS/REGON (gus.ts)
nie działa w tej wersji: BIR to usługa SOAP wymagająca klucza API i
zarządzania sesją, co jest poza zakresem wersji 1.0 — funkcja
getGusReport() zawsze rzuca RegistryError z jasnym komunikatem, zamiast
udawać, że coś zwraca. Testy nie wykonują żadnych realnych zapytań
sieciowych (mockowany fetch), dzięki czemu CI działa deterministycznie
offline.
Contributions are welcome! See CONTRIBUTING.md for the
development workflow and GOOD_FIRST_ISSUES.md for
ideas if you're looking for a place to start. This project follows the
Contributor Covenant.
MIT © 2026 Jakub Jagiełło