EU VAT Validation for SaaS Businesses
SaaS companies selling B2B across EU borders must validate customer VAT numbers to legally apply reverse charge. Integrate the TaxID API into your checkout and subscription flow to avoid VAT liability on unverified customers.
Under EU VAT Directive 2006/112/EC, a SaaS business supplying digital services to EU businesses can apply the reverse-charge mechanism, which shifts the VAT liability to the buyer. This is only valid when you can prove the buyer holds a valid, active VAT registration in their member state. Without verification, you are liable for the full VAT amount — regardless of what the customer claimed.
The TaxID API lets you verify any EU VAT number in real time against the VIES registry before issuing a zero-rated invoice. For each checkout or subscription activation, call GET /api/v1/validate/:country/:vat from your server and check that status is 'active'. Only then set the customer's tax treatment to reverse-charge in your billing system (Stripe, Paddle, or your own invoicing stack).
Subscription SaaS businesses face an ongoing compliance risk: VAT registrations can be cancelled after signup. A number valid at onboarding may be revoked six months later. Schedule a monthly background job to re-validate all reverse-charge customers and flag any returning 'invalid' status before the next billing cycle. The TaxID batch endpoint lets you validate up to 25 numbers per request, which is efficient for large customer lists.
Keep an audit trail: store the validated VAT number, the company_name and company_address from the TaxID response, and the validation timestamp on each invoice or subscription record. EU tax authorities in a VAT audit will ask for proof that the number was valid at the time of each transaction — not just at the time of signup.
Implementation steps
- 1
Get a free TaxID API key
Sign up at taxid.dev/signup. No credit card required. Store the key as an environment variable in your SaaS backend — never client-side.
- 2
Add a VAT number field to your SaaS checkout
Add a labeled VAT number input to your checkout or onboarding flow. Mark it as optional for consumers and required for customers who request B2B zero-rate treatment. Collect both the country code and the VAT number string.
- 3
Validate server-side before creating the subscription
Before completing checkout, call GET /api/v1/validate/:country/:vat from your server. If status is 'active', flag the customer as reverse-charge eligible and store the validated company details. If 'invalid', return a form error. If 'service_unavailable', charge standard VAT and follow up.
- 4
Apply reverse-charge in your billing system
Update the customer's billing record to reflect reverse-charge treatment. In Stripe, set tax_exempt: 'reverse'. In Paddle, use the customer tax ID field. In your own invoicing stack, add an 'RC' annotation to the invoice and set the VAT rate to zero.
- 5
Re-validate monthly for subscription customers
Run a background job at least once a month that re-calls the TaxID API for every reverse-charge customer. Flag any returning 'invalid' for your finance team to review before the next invoice cycle. Use the batch endpoint (POST /api/v1/validate) to validate up to 25 numbers in one request.
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
Frequently asked questions
Do I need to validate EU VAT numbers for every SaaS sale?
You need to validate when a customer claims B2B reverse-charge treatment (zero-rate VAT). Without a valid, verified VAT number, you cannot legally apply zero-rate — you must charge the standard VAT rate for the customer's country. Consumer sales (B2C) do not require VAT number validation.
What happens if I zero-rate an invoice without validating the VAT number?
The VAT liability falls on your business, not the customer. If a tax authority audits you and finds zero-rated invoices without verified VAT numbers, you will owe the full VAT amount plus interest and potentially penalties. The TaxID validation record (company_name, address, validation timestamp) is your proof of due diligence.
Which EU countries does TaxID cover for SaaS reverse-charge validation?
All 27 EU member states via VIES: Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, and Sweden.
How do I handle VIES downtime in my SaaS checkout?
If the TaxID API returns status: 'service_unavailable', do not silently zero-rate the customer. The safest fallback is to charge standard VAT and issue a credit note once VIES recovers. Alternatively, display a message asking the customer to retry in a few minutes. Always log service_unavailable events with customer ID and timestamp.
Further reading
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…
B2B VAT Exemption in EU SaaS: What Your Billing System Must Do
Reverse charge sounds simple but the implementation details trip up most SaaS billing engineers. Here is what your syste…
SaaS VAT Compliance: A Developer's Complete Guide for EU Markets
Selling a SaaS product to EU customers means navigating B2B vs B2C VAT rules, determining the place of supply, registeri…
Evaluating EU VAT APIs? Compare TaxID vs Vatstack, Vatlayer, Avalara →
Related use cases
Validate EU VAT numbers in Stripe Checkout
Add EU VAT validation to your Stripe checkout flow. Verify customer VAT numbers server-side before a...
UK VAT validation in Shopify B2B
Validate UK VAT numbers for B2B customers in Shopify. Required under UK Making Tax Digital rules for...
WooCommerce Spain NIF/CIF validation
Validate Spanish NIF and CIF numbers in WooCommerce checkout. Automatically apply B2B tax exemptions...