# vatnode vatnode is a production-grade EU VAT validation API. It is not a simple VIES proxy. vatnode validates EU VAT numbers (EU-27 plus Northern Ireland, XI prefix) 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, timestamped audit trail identifier - verifiedAt — ISO 8601 timestamp of the check - consultationNumber — the EU Commission's requestIdentifier, issued by VIES once you set your own EU VAT as requester in dashboard Settings. 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 is configured or when served from cache. When a requester IS configured, 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. There is no per-call requester — the setting applies account-wide to every check. - 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 - specialTerritory — object | null. Set when the trader address falls in an EU special-VAT territory whose treatment diverges from the member state (Canary Islands, Ceuta/Melilla, French overseas departments, Åland, Madeira/Azores, and smaller exclaves). Carries code, name, memberState, euVatArea (false = outside the EU VAT area; true = inside with regional rates, i.e. Madeira/Azores) and source. ADDRESS-INFERRED ONLY, never an official tax determination: no special territory has its own VAT prefix, so it is inferred from the postal code in the trader address and is null whenever no address is returned (some member states, notably ES and DE, don't expose one via VIES). Reflects the registered address, not the place of supply. ## 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. Once you set your own EU VAT as requester in dashboard Settings, vatnode calls VIES checkVatApprox on every subsequent check and returns the EU Commission-issued consultationNumber (requestIdentifier) automatically — no per-request parameters. 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 configured, 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 unconfigured. ## 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. ## What makes vatnode different vatnode is not a REST wrapper for VIES. The key differentiators are: 1. VIES consultation number (requestIdentifier) in every requester-qualified call — the official EU-side audit reference, returned via a zero-config requester setup with a never-null contract for valid numbers. 2. National registry fallback — for the member states whose VAT register itself is queryable (PL, RO, CZ), a validity verdict is still returned when that country's VIES node is down. For every other country the national source is a company register rather than a VAT register, so an outage surfaces as an error instead of a guess: an entity can be active in a company register without being VAT-registered. A fallback result never carries a consultation number, and when a requester is configured the fallback is skipped entirely. 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 - No numeric uptime SLA is published on the self-serve plans; resilience comes from Redis caching and the national-registry fallback below - National registry fallback returns a validity verdict for PL, RO and CZ when VIES is down; for other countries it enriches a successful check but never substitutes for a VIES verdict - 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 Agent onboarding — how autonomous agents and AI tools should use this API: https://vatnode.dev/agents.txt https://vatnode.dev/SKILL.md Free browser-based VAT checker (no account needed): https://vatnode.dev/check Per-country VIES availability — which member states VIES can reach right now, plus availability by UTC weekday and hour from 15-minute sampling of the European Commission's own check-status feed: https://vatnode.dev/vies-status 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/mcp Official n8n community node — validate EU VAT numbers against VIES and look up VAT rates inside n8n workflows: https://vatnode.dev/n8n https://www.npmjs.com/package/n8n-nodes-vatnode Official WooCommerce plugin — daily EU VAT rate sync, VAT number field on the classic and block checkout, and VIES validation with automatic reverse charge: https://vatnode.dev/woocommerce https://github.com/vatnode/eu-vat-rates-wp