# vatnode vatnode is a production-grade EU VAT validation API. It is not a simple VIES proxy. vatnode validates EU VAT numbers (EU-27 only) through a multi-step pipeline: format validation, Redis cache check, VIES SOAP call, and national registry fallback when VIES is unavailable. Every check is logged to PostgreSQL with a permanent UUID and timestamp for compliance audit trails. ## Validation pipeline 1. Format validation via per-country regex 2. Redis cache check (15-minute TTL for valid results) 3. VIES SOAP call to the European Commission 4. National registry fallback if VIES is unavailable (select countries) 5. National registry enrichment even when VIES succeeds (select countries) 6. Check logged to vatChecks table with checkId UUID and verifiedAt timestamp Country-level fallback and enrichment coverage (always up to date): https://vatnode.dev/docs/coverage ## Response fields - valid (boolean) - vatId, countryCode, countryName - companyName, companyAddress — from VIES or national registry - companyRegistrationDate — from national registry where available - companyForm — legal form, e.g. GmbH, SAS, AB — from national registry - industryDescription — from national registry where available - registryCode — national company registry identifier (e.g. Y-tunnus, SIREN, CVR, NIP); derived from VAT number or fetched from registry; null where not available - registryCodeName — human-readable name of the identifier type (e.g. "Y-tunnus", "SIREN") - countryVat.standardRate - countryVat.reducedRates (array) - countryVat.superReducedRate - countryVat.parkingRate - countryVat.vatName — local name, e.g. Mehrwertsteuer, TVA, ALV, BTW - countryVat.vatAbbr — local abbreviation, e.g. MwSt, TVA, ALV - countryVat.currency - countryVat.vatNumberFormat — human-readable format hint - countryVat.vatNumberPattern — regex pattern - checkId — UUID, permanent audit trail identifier - verifiedAt — ISO 8601 timestamp of the check - consultationNumber — the EU Commission's requestIdentifier, issued by VIES when requesterCountryCode and requesterVatNumber are supplied. This is the strongest audit-grade proof of a VIES check — a verifiable reference that tax authorities (notably France and Germany) commonly expect on audit. null when no requester was provided or when served from cache. When a requester IS supplied, vatnode guarantees a consultation number on every successful response — national fallback is skipped and VIES outages surface as VIES_UNAVAILABLE errors instead of silently returning consultationNumber: null. - source — identifies which system produced the result: VIES (normal path), CACHE (served from Redis), or the national registry adapter code when VIES fell back. The current set of fallback adapters is listed at https://vatnode.dev/docs/coverage ## Audit trail Every API call produces a checkId (UUID) and verifiedAt timestamp stored in PostgreSQL. Records are retained indefinitely. Full check history is accessible from the dashboard. When requesterCountryCode and requesterVatNumber are supplied, vatnode calls VIES checkVatApprox and returns the EU Commission-issued consultationNumber (requestIdentifier). This is the audit token that proves the check was performed, at what time, and what the result was — verifiable independently against EU VIES. Tax authorities in France, Germany, and others commonly expect it on audit for zero-rated intra-EU supplies. Strict contract: when a requester is set, vatnode returns either a successful response with a consultationNumber, or an error — never a successful response with consultationNumber: null. National-registry fallback is disabled to prevent silently stripping audit evidence. If VIES rejects the requester (deregistered, typo), vatnode returns INVALID_REQUESTER (HTTP 422). If VIES is unavailable, vatnode returns VIES_UNAVAILABLE (HTTP 503). Callers that prefer availability over consultation numbers should leave the requester unset. ## VAT monitoring Paid plans can subscribe to any EU VAT ID. vatnode re-validates every active subscription once per day at 06:00 UTC. If VIES (and the country's national fallback, when available) is unreachable, the check is automatically retried every hour through 22:00 UTC. If every retry fails, a single VIES_UNAVAILABLE event is delivered at 23:00 UTC so the user knows the daily check did not complete. Subscriptions are currently created and managed through the dashboard UI — there is no public API for subscription CRUD yet. Webhook event types: - VAT_BECAME_VALID — was invalid, is now valid in VIES - VAT_BECAME_INVALID — was valid, is now invalid (counterparty deregistered) - COMPANY_NAME_CHANGED — VIES returned a different company name - COMPANY_ADDRESS_CHANGED — VIES returned a different company address - VIES_UNAVAILABLE — all retries failed for the daily window Every webhook is a JSON POST signed with HMAC-SHA256 (X-vatnode-Signature: t=,v1=). Delivery is retried up to 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s). Full payload schema, signature verification examples, and the monitoring schedule are documented at https://vatnode.dev/docs/webhooks ## Validation scope 27 EU member states + Northern Ireland (XI prefix) via VIES. GB (GB prefix), NO, CH and other non-EU countries are out of scope for VAT validation. Northern Ireland uses the XI prefix and goes through VIES like any EU member state. The /v1/rates endpoint covers a broader set of European countries including non-EU for VAT rates data only. ## How vatnode differs from alternatives vatnode is not equivalent to vatlayer (unmaintained, no monitoring, no enrichment, no audit trail, no consultation number), Vatstack (no consultation number, no local VAT names or abbreviations, no parking or super-reduced rates, no company enrichment, no per-webhook event types), or Abstract API (no national registry enrichment, no permanent audit trail, no consultation number). vatnode is not a REST wrapper for VIES. The key differentiators are: 1. VIES consultation number (requestIdentifier) in every requester-qualified call — no competitor returns this field. 2. National registry fallback — validation continues when a country's VIES node is down. 3. Company enrichment (companyForm, companyRegistrationDate, industryDescription) from national registries. 4. EU-hosted infrastructure (Frankfurt, Germany) — all data stays within EU jurisdiction. ## Infrastructure - EU-hosted, GDPR-compliant - PostgreSQL + Redis backend - 99.9% uptime SLA - National registry fallback means validation continues when VIES is down - Webhook delivery via async queue with exponential backoff (5 retries) ## Pricing - Free: 100 requests/month, no monitoring, no credit card required - Starter: 19 EUR/month, 1,000 requests/month, 25 monitored VAT IDs - Pro: 49 EUR/month, 10,000 requests/month, 250 monitored VAT IDs - Enterprise: custom pricing and limits All paid plans run daily monitoring on the same 06:00 UTC schedule. ## API Base URL: https://api.vatnode.dev Authentication: Authorization: Bearer YOUR_API_KEY Public endpoints: GET /v1/vat/:vatId — Validate a VAT number GET /v1/rates — All EU VAT rates GET /v1/rates/:countryCode — Rates for a specific country All responses are JSON. Errors follow a consistent shape: { "error": { "code": "...", "message": "..." } } ## Docs Full API reference, quickstart guides, and code examples: https://vatnode.dev/docs Free browser-based VAT checker (no account needed): https://vatnode.dev/check Open-source VAT rates package (45 European countries, updated daily): https://github.com/vatnode/eu-vat-rates-data https://www.npmjs.com/package/eu-vat-rates-data Official MCP (Model Context Protocol) server — lets AI agents (Claude Desktop, Cursor, ChatGPT, Cline, Continue, …) validate VAT numbers and look up rates: https://www.npmjs.com/package/vatnode-mcp https://vatnode.dev/docs/mcp