Country Guide9 min readAlberto García

Polish VAT Number Validation: NIP Format, VIES, and Code Examples

Polish NIP numbers use PL + 10 digits. The 10th digit is a check digit computed from the first 9. Polish numbers are often formatted with hyphens on invoices — strip them before validation.

polandplnip

Poland is one of the EU's largest and fastest-growing economies, and an increasingly significant source of B2B customers for European SaaS platforms — particularly in software development, manufacturing, and business services. Polish VAT numbers, the NIP (Numer Identyfikacji Podatkowej), follow a clean numeric format of PL + 10 digits with a check digit. The main integration gotcha is that Polish invoices and business documents almost always format the NIP with hyphens, which must be stripped before validation. This guide covers the format, check digit, common errors, VIES behaviour, and complete code examples.

Note

Polish VAT numbers (NIP — Numer Identyfikacji Podatkowej) are issued and managed by the Krajowa Administracja Skarbowa (KAS). VIES routes Polish validation requests to the KAS system in real time.

The Polish VAT Number Format (NIP)

A Polish VAT number consists of the prefix PL followed by exactly 10 digits — 12 characters in total. There are no letters after the prefix and no separators in the canonical form. A valid example is PL1234567890. The 10th digit is a check digit computed from the first 9 digits using a weighted sum algorithm with the weights [6, 5, 7, 2, 3, 4, 5, 6, 7], modulo 11.

On Polish invoices and business documents, the NIP is typically formatted with hyphens as XXX-XXX-XX-XX (e.g., 123-456-78-90) or occasionally as XXX-XX-XX-XXX. Both formats represent the same 10-digit number. Always strip hyphens, spaces, and all other non-alphanumeric characters before validation. The TaxID API accepts numbers with hyphens and strips them internally, but stripping client-side before the API call is good practice.

PropertyValue
PrefixPL
Total length12 characters (PL + 10 digits)
FormatPL followed by 10 numeric digits
ExamplePL1234567890
Common invoice formatPL 123-456-78-90
Regex^PL[0-9]{10}$
VIES country codePL
National authorityKrajowa Administracja Skarbowa (KAS)
Local nameNumer Identyfikacji Podatkowej (NIP)

Common Polish VAT Format Errors

  • Hyphens not stripped: '123-456-78-90' submitted instead of '1234567890' — the most common error. Polish invoices always format NIP with hyphens. Strip before validation.
  • Missing PL prefix: '1234567890' without the PL country code. Unlike Germany where you should not silently add the prefix, Poland's 10-digit format is fairly distinctive — but always ask for the full VIES-format number.
  • Submitting REGON instead of NIP: REGON (Rejestr Gospodarki Narodowej) is a 9-digit or 14-digit statistical identifier, not a VAT number. If a customer submits a 9-digit or 14-digit number, they may have submitted their REGON.
  • Wrong digit count: Polish NIP is always 10 digits after PL. A 9-digit number (common mistake by customers who omit a digit) fails format validation.
  • Lowercase: 'pl1234567890' — normalise to uppercase before validation.
  • Check digit failure: a customer who mistyped one digit in their NIP will pass the basic format check (PL + 10 digits) but fail check digit validation. The TaxID API catches this locally before the VIES call.

Polish Company Types and VAT Registration

The most common Polish legal forms for B2B customers are sp. z o.o. (spółka z ograniczoną odpowiedzialnością — equivalent to a GmbH or LLC, the most common form for Polish SMEs and startups), S.A. (spółka akcyjna — public company for larger corporations), and JDG (jednoosobowa działalność gospodarcza — sole trader / self-employed individual). Polish tech companies and agencies almost universally use the sp. z o.o. form. JDG sole traders who are VAT-registered have a NIP derived from their personal PESEL number.

Polish businesses with annual taxable revenue below PLN 200,000 (~€45,000) can opt for VAT exemption (zwolnienie podmiotowe). These businesses have a NIP for income tax purposes but are not registered for VAT and cannot receive reverse charge treatment. If a Polish customer claims they have a NIP but are not VAT-registered, they are likely on the zwolnienie podmiotowe exemption. VIES will typically return inactive or not_registered for their NIP. Charge the applicable VAT rate for such customers — they are not VAT-exempt for reverse charge purposes.

VIES and Poland's KAS: What to Expect

Poland's KAS VIES endpoint is generally reliable and well-maintained. Response times for live VIES lookups are typically 200-600ms. Poland introduced additional VAT enforcement measures (the Split Payment Mechanism — mechanizm podzielonej płatności) in 2019, which has motivated KAS to maintain a high-quality VAT registration database. VIES data for Polish companies is generally accurate and up to date.

Poland returns company name and registered address via VIES in most cases. The company name is the official KRS (Krajowy Rejestr Sądowy — National Court Register) registered name for companies, or the individual's name and trading name for JDG sole traders. Polish VAT validation via TaxID caches active results for 24 hours. For the allow-and-re-validate pattern during KAS maintenance windows, see VIES Downtime: Building a Resilient Validation Flow.

Polish VAT Rates

Poland applies a standard VAT rate of 23% to most goods and services — one of the highest standard rates in the EU. An 8% reduced rate applies to food products for human consumption, medical devices, hotel accommodation, and passenger transport. A 5% reduced rate applies to basic food staples (bread, meat, dairy, processed foods), books and e-books, and certain agricultural products. A 0% rate applies to intra-EU B2B supplies with reverse charge, certain financial services, and some exports.

For SaaS and digital services sold to Polish consumers (B2C), the applicable rate is 23%. For Polish B2B customers with a valid NIP that validates active via VIES, zero-rate reverse charge applies. Poland fully participates in the EU OSS scheme for B2C digital services.

Code Examples

cURL

bash
# Validate a Polish VAT number (NIP)
curl https://taxid.dev/api/v1/validate/PL/PL1234567890 \
  -H "Authorization: Bearer YOUR_API_KEY"

# Expected response:
# {
#   "valid": true,
#   "status": "active",
#   "vat": "PL1234567890",
#   "country_code": "PL",
#   "company_name": "Przykład sp. z o.o.",
#   "address": "ul. Marszałkowska 1, 00-001 Warszawa",
#   "cached": false,
#   "request_id": "req_01j..."
# }

Node.js / TypeScript

typescriptvalidate-polish-vat.ts
export async function validatePolishVat(vatNumber: string): Promise<{
  valid: boolean;
  companyName: string | null;
  address: string | null;
  status: string;
}> {
  // Strip hyphens — Polish invoices always format NIP as XXX-XXX-XX-XX
  const normalised = vatNumber.replace(/[\s-]/g, '').toUpperCase();

  // PL + exactly 10 digits
  if (!/^PL[0-9]{10}$/.test(normalised)) {
    return { valid: false, companyName: null, address: null, status: 'format_invalid' };
  }

  const res = await fetch(
    `https://taxid.dev/api/v1/validate/PL/${normalised}`,
    {
      headers: { Authorization: `Bearer ${process.env.TAXID_API_KEY}` },
      signal: AbortSignal.timeout(5000),
    }
  );

  const data = await res.json();
  return {
    valid: data.valid,
    companyName: data.company_name,
    address: data.address,
    status: data.status,
  };
}

Python

pythonvalidate_polish_vat.py
import re, os, requests
from dataclasses import dataclass
from typing import Optional

PL_PATTERN = re.compile(r'^PL[0-9]{10}$')

@dataclass
class PolishVatResult:
    valid: bool
    company_name: Optional[str]
    address: Optional[str]
    status: str

def validate_polish_vat(vat: str) -> PolishVatResult:
    # Strip hyphens — Polish invoices format NIP as XXX-XXX-XX-XX
    normalised = re.sub(r'[\s-]', '', vat).upper()
    if not PL_PATTERN.match(normalised):
        return PolishVatResult(False, None, None, 'format_invalid')

    r = requests.get(
        f'https://taxid.dev/api/v1/validate/PL/{normalised}',
        headers={'Authorization': f'Bearer {os.environ["TAXID_API_KEY"]}'},
        timeout=5,
    )
    r.raise_for_status()
    d = r.json()
    return PolishVatResult(
        valid=d['valid'],
        company_name=d.get('company_name'),
        address=d.get('address'),
        status=d['status'],
    )

Frequently Asked Questions

  • Is PL always the VIES code for Poland? Yes. Poland uses PL as its ISO code and VIES prefix.
  • What is the difference between NIP, REGON, and KRS? NIP is the tax identification number (used for VIES). REGON is a 9 or 14-digit statistical identifier for the Central Statistical Office. KRS is the National Court Register number for registered companies. Only NIP is relevant for EU VAT validation.
  • Why is the Polish NIP always formatted with hyphens on invoices? Polish tax law requires NIP to be displayed with hyphens in the format XXX-XXX-XX-XX on invoices and documents. This is a display convention only — the underlying number is 10 digits without separators. Always strip hyphens before API calls.
  • Can a Polish sole trader (JDG) receive reverse charge treatment? Yes. Polish JDG sole traders who are VAT-registered have a valid NIP and can receive zero-rate reverse charge treatment. Confirm active VIES status before applying zero rate.
  • What does zwolnienie podmiotowe mean? It is the Polish VAT exemption for businesses below PLN 200,000 annual revenue. These businesses have a NIP for income tax but are not VAT-registered — their NIP will typically not be active in VIES.

Validating Polish VAT Numbers at Scale

Poland's KAS system is one of the more reliable VIES endpoints, making bulk validation straightforward. For ERP systems importing Polish supplier records or platforms onboarding Polish sellers, the main pre-processing step is stripping hyphens from NIP values. TaxID caches active Polish VAT results for 24 hours — repeated validations of the same NIP within 24 hours return the cached result instantly. Store the request_id from each response for audit traceability. For the complete format reference and live validator, see validate-vat/pl.

Start validating EU VAT numbers

Free plan — 100 validations/month. No credit card required.

AG
Alberto García

Founder, TaxID

Building EU VAT validation tools for developers. Obsessed with compliance automation and developer experience.