NIP, NIF, AFM: National Tax ID Inside an EU VAT Number
4 Nov 2026

In many EU countries the national tax ID is already inside the VAT number: strip the two-letter prefix and what is left is the Polish NIP, the Spanish NIF or the Greek ΑΦΜ. In others the ID is a reformatted slice of the VAT number, and in the rest the two are different numbers. vatnode’s GET /v1/vat/{vatId} returns taxId and taxIdName where the mapping is unambiguous and null where it is not.
You can read taxId from a real response with a free API key, no card needed. Test keys return null for it, so a live call is the only way to see a populated value.
Is a national tax ID the same as a VAT number?
It depends on the country. The VAT number is the EU-level identifier: country prefix plus a national part. The tax ID is the number the national tax authority gave the taxpayer, whether or not they ever registered for VAT. The general concept is in VAT number vs tax ID; this post covers the countries where the two overlap.
There are three cases:
- The VAT number is the prefix plus the tax ID. Poland, Spain, Greece, Portugal and several others.
taxIdis the part after the prefix. - The tax ID is derivable, but written differently. Finland, France, Belgium, the Czech Republic. The digits are in the VAT number; the national format is not.
- The two are not the same number, or not always. Germany and Italy are the usual examples.
taxIdisnull.
A tax ID inside a VAT number does not tell you the taxpayer is VAT-registered: every taxpayer has a tax ID, and many never register for VAT. valid is the only field that says anything about VIES.
NIP in Poland, NIF in Spain, AFM in Greece
For these countries the suffix is the ID. The examples below are fictitious and deliberately fail the national checksum, so they cannot belong to a real taxpayer:
| Country | VAT number (fictitious) | taxId | taxIdName |
|---|---|---|---|
| Poland | PL1234567890 | 1234567890 | NIP |
| Spain | ESB12345670 | B12345670 | Número de Identificación Fiscal |
| Greece | EL123456789 | 123456789 | ΑΦΜ |
Poland. The Polish VAT number is PL plus the 10-digit NIP number. Polish businesses need a VAT-UE registration to trade intra-EU, so holding a NIP is not enough. A private individual without a business uses the PESEL as a tax identifier, not a NIP. More in validating Polish VAT numbers and the Poland VAT API reference.
Spain. The Spanish VAT number is ES plus the NIF. For a legal entity the NIF is a letter, seven digits and a check character. For a Spaniard it is the DNI (eight digits and a letter), for a foreigner the NIE (X, Y or Z, seven digits and a letter). K, L and M forms cover individuals without a DNI or NIE, such as minors and Spaniards living abroad. So the NIF is not only the DNI. A business also has to be in the Registro de Operadores Intracomunitarios (ROI) to trade intra-EU, so a correct-looking number still proves nothing about VIES. See Spanish VAT numbers in Node.js and the Spain VAT API reference.
Greece. The ΑΦΜ (Αριθμός Φορολογικού Μητρώου) has 9 digits, and the VAT number is EL plus the ΑΦΜ. VIES and the EU use EL, derived from Ελλάδα, while ISO uses GR. The Greek Node.js guide and the Greece VAT API page cover the prefix in detail. Portugal works the same way; see validating Portuguese VAT numbers.
The taxIdName values are the literal strings from vatnode’s dataset: the name in the country’s first official language. For Spain that is the spelled-out Número de Identificación Fiscal, not the abbreviation.
Why you searched for CIF in Spain
If you searched for a ‘CIF number in Spain’: CIF (Código de Identificación Fiscal) was the tax number for companies and other legal entities. Royal Decree 1065/2007 replaced it with the NIF for legal entities from 2008. The structure stayed the same (a letter, seven digits and a control character), and CIF survives in everyday speech and older invoice templates.
For the API this means there is no separate CIF field. A Spanish company’s CIF is its NIF, and it comes back as taxId.
When the ID is formatted or derived, not copied
In some countries the tax ID is in the VAT number but the national notation differs from what you typed. The examples are fictitious and fail the national checksum:
| Country | VAT number (fictitious) | taxId | Note |
|---|---|---|---|
| Finland | FI12345670 | 1234567-0 | Y-tunnus, hyphen before the last digit |
| France | FR12123456789 | 123 456 789 | SIREN taken from the end, grouped in threes |
| Belgium | BE0123456789 | 0123.456.789 | ondernemingsnummer, dotted |
| Czech Republic | CZ12345678 | CZ12345678 | DIČ is CZ plus the 8-digit IČO, prefix included |
Two Czech details matter in code. The taxId includes the CZ prefix, unlike Poland, Spain, Greece or Portugal, where only the suffix comes back. And Czech individuals usually have a DIČ built on their rodné číslo (9 or 10 digits); for those vatnode returns taxId: null. Usually, not always: since 2021 individuals can request a separate identifier.
Sweden follows the same pattern with a guard. A company’s VAT number is SE, its 10-digit organisationsnummer and 01, and taxId is that organisationsnummer written NNNNNN-NNNN. A sole trader’s VAT number is built on a personnummer instead, and for those taxId is null. For the mirror-image field see company number vs VAT number, which covers registryCode.
The formats are listed in the EU VAT number formats guide.
Where taxId is deliberately null
taxId is null whenever the VAT number is not demonstrably the national tax number, and the rule is the same everywhere. This is where stripping the prefix yourself goes wrong, because it can give you a number that is not the tax ID:
- Italy. The partita IVA is the VAT number, not the codice fiscale, and the two differ for VAT groups and sole traders.
- Germany. The USt-IdNr (
DEplus 9 digits, issued by the BZSt) is a separate number from the Steuernummer, so nothing can be derived. - Bulgaria. A 9-digit suffix is the company registry number, so
registryCodeis filled whiletaxIdisnull. A 10-digit suffix is not read as a registry number: it can be a legacy number built on a personal ID or a service number issued by the tax authority to individuals outside the business registers (in use since 1 January 2024), so every field isnull.
The same applies wherever the suffix is only sometimes the tax number: null there is the correct answer. The taxId column of coverage lists which countries return it and is the one place that list is kept current.
Reading taxId and taxIdName from the API
The endpoint is GET https://api.vatnode.dev/v1/vat/{vatId}, authenticated with Authorization: Bearer <key>:
curl https://api.vatnode.dev/v1/vat/PL1234567890 \
-H "Authorization: Bearer $VATNODE_API_KEY"
The response below is trimmed to the relevant fields and is illustrative. The number fails the Polish checksum, and vatnode’s own format check is regex-only, so a real call with it would go on to VIES and would not come back valid. A successful check has this shape:
{
"valid": true,
"vatId": "PL1234567890",
"countryCode": "PL",
"companyName": "EXAMPLE SPÓŁKA Z O.O.",
"registryCode": null,
"registryCodeName": null,
"taxId": "1234567890",
"taxIdName": "NIP"
}
In Node.js, server-side, because the key must never reach browser code:
async function nationalTaxId(vatId) {
const res = await fetch(`https://api.vatnode.dev/v1/vat/${encodeURIComponent(vatId)}`, {
headers: { Authorization: `Bearer ${process.env.VATNODE_API_KEY}` },
})
if (!res.ok) {
// An error means 'could not check', never 'invalid'
const body = await res.json().catch(() => null)
throw new Error(`vatnode request failed: ${body?.error?.code ?? res.status}`)
}
const check = await res.json()
if (!check.valid) return { ok: true, valid: false }
// taxId is null where the VAT number is not the national tax number
const { taxId, taxIdName } = check
return { ok: true, valid: true, taxId, taxIdName }
}
A 503 with VIES_UNAVAILABLE means the member-state service was down: retry later and don’t treat the number as invalid. Build around these behaviours:
- It is parsed, not looked up.
taxIdis derived from the string you sent, on every live result, including whenvalidisfalse. It confirms nothing beyondvalid, so gate onvalidfirst. - Name and number travel together.
taxIdNameisnullexactly whentaxIdisnull. - Test keys never populate it. A
vat_test_key accepts only theXXfixture numbers, and those returntaxId: null, so you cannot see a populated value in test mode. - Error responses carry no
taxId. A non-2xx response holds anerrorobject instead, so handle the HTTP status before reading the body. When VIES is down and a national fallback answers, the result is an ordinary one andtaxIdis derived as usual. See format vs valid for why a well-formed number is not a valid one.
Get a free key, then the quickstart has the full request, and the free checker lets you try a number without code.
Names without a number: identifiers in /v1/rates
If you only need what a country calls its tax ID, for a form label for instance, you don’t need a check at all. GET https://api.vatnode.dev/v1/rates/{countryCode} is public, needs no key (the rates endpoint reference has the full response), and returns an identifiers block with names only: taxIdName, registryCodeName, registryName, registryAuthorityName and vatIdName, each a map of language to name including en. For Poland, taxIdName is { "pl": "NIP", "en": "tax identification number" }.
This endpoint keys Greece by the ISO code GR, and it also accepts the VAT prefix EL and answers as GR. The same block is nested in /v1/vat as countryVat.identifiers. It never contains a number. See the rates reference. The names come without a key; a number comes only from a check.
Privacy: the ID can identify a person
For a company, a tax number identifies the business. For a sole trader it is usually tied to the person: the Spanish NIF of an individual is the DNI or NIE, and a Greek ΑΦΜ, a Portuguese NIF or the NIP of an individual trader identify that individual. Those are personal data under Article 4(1) GDPR, exactly as the VAT number they were parsed from.
Current behaviour: for Swedish personnummer and for Czech or Bulgarian personal-number VAT IDs, taxId is null. For Spanish, Greek, Portuguese and Polish individuals’ numbers it is returned as it appears in the VAT number.
taxId adds no new information. It is the same digits your customer gave you, reformatted, and you can derive it from the number you already hold.
There is no reason to copy it into a separate column, a search index, a log line or an analytics event. If you need it printed on an invoice, keep it with that invoice record under the same retention as the invoice, in line with data minimisation (Art. 5(1)(c)). Art. 87 GDPR lets member states set extra conditions for national identification numbers; where a tax number doubles as one, as with a DNI-based Spanish NIF, check the local rules before using it beyond invoicing and tax. See storing VAT data under GDPR and company data enrichment for what else a check returns.
FAQ
Is the NIP the same as the VAT number in Poland?
Almost. The Polish VAT number is the prefix PL followed by the 10-digit NIP, so the NIP is the part after PL. A NIP alone is not a VAT number in the cross-border sense, and having a NIP does not mean the business is registered for intra-EU trade. Private individuals without a business use a different number, the PESEL, as their tax identifier.
What is the difference between NIF, CIF and the Spanish VAT number?
NIF stands for Número de Identificación Fiscal and is Spain’s tax identification number. CIF was the old name for the NIF of companies and other legal entities, and it was folded into the NIF in 2008, though people still say it. The Spanish VAT number is ES followed by the NIF. For a company the NIF is a letter, seven digits and a check character. For a Spanish individual it is the DNI, and for a foreigner the NIE.
Is the Greek ΑΦΜ the same as the EL VAT number?
Yes, in the sense that the Greek VAT number is the prefix EL followed by the 9-digit ΑΦΜ (Αριθμός Φορολογικού Μητρώου). The prefix is EL in VIES and in the vatId the vatnode API returns, while ISO country data, including the countryCode field in that response, uses GR. Holding an ΑΦΜ does not by itself mean the taxpayer is active in VIES.
How do I get the national tax ID from an EU VAT number via API?
Call GET /v1/vat/ with your API key and read taxId and taxIdName from the response. The value is parsed from the VAT number you sent, in the country’s national format, not looked up in a register. It is returned even when valid is false, so check valid first and treat taxId as a reformatted copy of the input.
Does the API return the national tax ID for every EU country?
No. taxId is returned only where the VAT number maps unambiguously to a national tax number. Where the two differ or can differ, for example in Italy and Germany, taxId is null. The per-country list is in the coverage reference at /docs/coverage.
Read taxId from a real check
Get a free API key and read taxId from your own code. The free plan needs no card. The request and response fields are in the API docs, and the free checker lets you try any number without code.
This article explains how the API field behaves. It is not legal or tax advice. How you process tax identifiers depends on your own setup and the rules where you operate.