惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
V
Visual Studio Blog
罗磊的独立博客
Last Week in AI
Last Week in AI
爱范儿
爱范儿
The Cloudflare Blog
有赞技术团队
有赞技术团队
博客园 - 三生石上(FineUI控件)
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 司徒正美
IT之家
IT之家
博客园 - 【当耐特】
雷峰网
雷峰网
博客园_首页
Jina AI
Jina AI
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
量子位
V
V2EX

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
EU VAT validation API's: a practical comparison
BitOwl · 2026-06-17 · via DEV Community

At some point in every B2B SaaS project, someone asks: "can we skip tax for EU business customers?". And then you spend a friday afternoon finding out... yes, you can, but you need to validate their VAT numbers first. And that opens a whole thing.

This is what I found, from my experience with VAT number in our global SaaS service.

Option 1: VIES directly

"VIES" is the official EU VAT database. It's run by the European Commission and it's free to use! Those are the good parts.

The bad is that it's a SOAP API from around 2003 and it really shows... You write raw XML, send over HTTP, and parse XML back. Error states come back as HTTP 200:s with fault codes buried in the body. Some member countries return full company names. Others return nothing. Germany is known for returning MS_UNAVAILABLE during regular business hours for no obvious reason.

Here's a minimal request:

curl -s https://ec.europa.eu/taxation_customs/vies/services/checkVatService \
  -H "Content-Type: text/xml" \
  -d '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:urn="urn:ec.europa.eu:taxud:vies:services:checkVat:types">
  <soapenv:Body>
    <urn:checkVat>
      <urn:countryCode>SE</urn:countryCode>
      <urn:vatNumber>556543123401</urn:vatNumber>
    </urn:checkVat>
  </soapenv:Body>
</soapenv:Envelope>'

It works. Just budget time for XML parsing, error handling, and tests for the unavailable-state edge cases.

Pros: free, no rate limits, no third party in the chain
Cons: XML, inconsistent responses per country, no UK support (post-Brexit), needs defensive error handling

Option 2: VatLayer / Abstract API / Vatstack

A bunch of services wrap VIES in a REST API, which solves the XML problem. The docs are good and the responses are consistent.

The catch is that most charge from the very first request. No real free tier. If you're running validations in development and staging too, costs add up before you've even shipped. I also noticed one service routing all lookups through a single US region, which adds unnecessary latency and possible compliance issue for European customers.

Pros: clean REST API, no XML
Cons: cost starts from day one, EU-only coverage on most plans

Option 3: TaxVett

TaxVett is what I ended up using lately. Free lookups every month, no credit card needed, and it covers not just EU but also UK. And for the future there's also Norway, Australia and Singapore in the same API. For our service with companies globally that's is very useful.

The request is simple:

curl -X POST https://api.taxvett.com/v1/validate \
  -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"number": "SE556543123401"}'

Response:

{
  "valid": true,
  "number": "SE556543123401",
  "country": "SE",
  "regime": "eu_vat",
  "verification_method": "live_registry",
  "company_name": "Acme AB",
  "company_address": "Stockholm, Sweden"
}

Country is auto-detected from the number prefix, so you don't need to pass it unless the format is ambiguous. If VIES is unavailable for a specific country, you get a proper error back in the same JSON shape rather than a silent success.

For UK numbers, it routes to HMRC instead of VIES. There's a separate post on UK VAT validation here if you need that specifically.

Pros: free to start, REST API, consistent response across all countries, covers UK/AU/NO/SG too
Cons: third-party dependency, paid plans kick in at higher volumes (from 9 EUR/month)

How do I integrated in Node.js?

async function validateVatNumber(vatNumber: string): Promise<{
  valid: boolean;
  companyName?: string;
}> {
  const response = await fetch("https://api.taxvett.com/v1/validate", {
    method: "POST",
    headers: {
      "X-Api-Key": process.env.TAXVETT_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ number: vatNumber }),
  });

  if (!response.ok) {
    // 422 = format invalid, 404 = not found in registry
    return { valid: false };
  }

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

When valid is true, I also prefill the company name in the checkout form. Saves the customer a step and feels polished.

The batch endpoint?

If you need to validate existing customers in bulk, there's also a batch endpoint:

curl -X POST https://api.taxvett.com/v1/validate/batch \
  -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "numbers": [
      {"number": "SE556543123401"},
      {"number": "DE123456789"},
      {"number": "FR12345678901"}
    ]
  }'

I batch 50 per request. Each one counts against your quota separately, which matters if you're on the free plan.

What to pick?

If you're EU-only and happy with XML and error handling: VIES directly is totally fine and free.

If you want a clean API and are selling into multiple regions: a wrapper is worth it! TaxVett is the only one I found with a real free tier, that made it easy to evaluate without committing.