Validate German USt-IdNr. (DE VAT numbers)
Specifically validate German Umsatzsteuer-Identifikationsnummern (USt-IdNr.) via VIES. Understand the difference between the local Steuernummer and the EU VAT number.
Germany issues two distinct tax numbers to businesses: the Steuernummer (a domestic 10–13 digit number used for income tax filings with the Finanzamt) and the Umsatzsteuer-Identifikationsnummer (USt-IdNr.), which is the EU VAT number prefixed with DE followed by exactly 9 digits (e.g. DE123456789). Only the USt-IdNr. is registered in VIES and valid for cross-border B2B transactions; the Steuernummer cannot be used for reverse-charge invoicing and should not be accepted as a substitute.
German companies can look up their USt-IdNr. through the Bundeszentralamt für Steuern (BZSt). When a German buyer provides a 10–13 digit number without the DE prefix, it is almost certainly a Steuernummer — your validation UI should detect this pattern and prompt the user to enter their EU VAT number instead rather than passing it to the API as a malformed request.
The Bundeszentralamt für Steuern also offers a qualified confirmation service (qualifizierte Bestätigungsabfrage) that checks whether a specific company name and address matches the VIES record, not just whether the number is valid. TaxID returns the company_name and company_address fields from VIES, so you can implement this cross-check locally by comparing the VIES-returned company name against the name provided by the buyer, flagging significant mismatches for manual review.
Implementation steps
- 1
Accept DE prefix with 9 digits
Validate the format client-side with the regex /^DE[0-9]{9}$/ before calling the API. If the input matches a Steuernummer pattern (/^[0-9]{10,13}$/ without a country prefix), surface a specific message explaining the difference: 'This looks like a Steuernummer. Please enter your EU USt-IdNr. starting with DE.' This prevents unnecessary API calls for a format that VIES will always reject.
- 2
Validate format before VIES call
Strip whitespace and slashes from the input, then call GET /api/v1/validate/DE/:vatNumber. The API will forward the request to the German BZSt node in VIES; response times for German lookups are typically 200–800 ms, so set a client-side timeout of at least 5 seconds and show a loading indicator to prevent users from submitting the form before the response arrives.
- 3
Handle German Tax Agency response times
The BZSt VIES node is one of the more reliable EU nodes but can return service_unavailable during system maintenance windows (typically early morning CET). When this occurs, do not block the user's checkout or form submission; instead, persist a vat_pending_validation flag on the record and queue a background re-validation job that retries every 15 minutes for up to 4 hours before escalating to manual review.
- 4
Return company name and address if available
The TaxID API returns company_name and company_address from the VIES response for German numbers when the BZSt node provides them. Display the company_name on screen as a confirmation step — for high-value B2B transactions, prompt the buyer to confirm 'Is this your company: [company_name]?' before proceeding. Store both fields alongside the order for your accounts-receivable team and for inclusion on reverse-charge invoices.
Code example
Node.js
const res = await fetch(
'http://localhost:3000/api/v1/validate/DE/DE123456789',
{ headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const { valid, status, company_name, company_address } = await res.json();
if (valid) {
console.log(`Valid EU business: ${company_name}`);
} else if (status === 'service_unavailable') {
// VIES is temporarily down — retry or allow with manual check
console.log('VIES unavailable — check back in a few minutes');
} else {
console.log('Invalid VAT number — charge local tax rate');
}Python
import requests
res = requests.get(
"http://localhost:3000/api/v1/validate/DE/DE123456789",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = res.json()
if data["valid"]:
print(f"Valid: {data['company_name']}")
elif data["status"] == "service_unavailable":
print("VIES temporarily unavailable")
else:
print("Invalid VAT number")API response
The TaxID API returns a consistent JSON response for every validation request:
{
"valid": true,
"status": "active",
"country_code": "DE",
"vat_number": "123456789",
"company_name": "Example GmbH",
"company_address": "Musterstraße 1, 10115 Berlin",
"request_date": "2026-05-10T00:00:00.000Z",
"cached": false,
"request_id": "req_01j..."
}Error handling
The API uses a consistent Stripe-style error format. Always handle service_unavailable separately — VIES has occasional downtime and you should not reject valid customers during outages.
activeVAT number is valid and the business is registered
invalidVAT number format is wrong or not registered in VIES
service_unavailableVIES or the national system is temporarily down — retry later
Country-specific guides
Further reading
German VAT Number Validation: USt-IdNr Format, VIES, and Common Errors
German USt-IdNr numbers follow DE + 9 digits. But format-valid numbers can still fail VIES. Here is everything a develop…
EU VAT Number Validation: The Complete Developer Guide (2026)
VIES is SOAP-based, unreliable, and has no caching. This guide explains how EU VAT validation works end-to-end, how to h…
Evaluating EU VAT APIs? Compare TaxID with:
Related use cases
EU VAT compliance for SaaS billing
Handle EU VAT for SaaS subscriptions. Validate customer VAT numbers at signup, determine B2B vs B2C ...
DAC7 marketplace seller VAT verification
Verify seller VAT numbers during marketplace onboarding for DAC7 compliance. EU platforms must colle...
Bulk VAT number validation via CSV import
Validate hundreds of EU VAT numbers in batch using parallel API requests. Ideal for CRM data cleansi...