Iurii RoguliaIurii Rogulia
AboutServicesPricingProjectsStackReviewsPhrasesBlog
Contact
Iurii ships.

Iurii Rogulia, senior full-stack software engineer. Professionally building software since 2001.

Think of a number
PricingQuality checklistPrivacy PolicyCookie Policy

Business

TMI Iurii Rogulia
VAT ID: FI29845875
DUNS: 368664211
Lappeenranta, Finland 🇫🇮

[email protected]
Back to projects

Iurii Automates: n8n Verified Community Node – EU VAT Validation in Workflows

August 6, 2026

Verified n8n node that puts VIES VAT validation and EU rate lookups inside a workflow, so onboarding or invoicing can decide on a real VAT number instead of a well-formed one.

View on npm Source code

Stack

TypeScriptNode.jsn8n

Services

npmGitHub Actionsvatnode API

Topics

Workflow AutomationNo-CodeIntegrationsDeveloper ToolsOpen SourceTax/VAT

Key Results

  • Passed n8n’s review – live on n8n Cloud and addable straight from the workflow canvas
  • A workflow can act on whether a VAT number is real, not merely well-formed
  • Free operations – format check and rate lookup – run with no account and no quota
  • The VIES consultation number lands in the workflow as audit evidence for the customer record
  • Available to any n8n AI agent as a callable tool, no glue code
n8n Verified Community Node – EU VAT Validation in Workflows

npm

Downloads

License

The Business Problem

The people who most need a VAT number checked are usually not the people who can call an API. A finance operations lead onboarding B2B customers, an agency automating invoicing, a founder wiring together a signup flow – they build in n8n, and in n8n a VAT number was just a string.

What they could do with a regular expression is confirm a number looks like a German VAT number. What decides whether an invoice carries VAT is whether that number is actually registered – and the official EU register, VIES, speaks SOAP over an endpoint that goes down country by country. Reaching it from a no-code tool means an HTTP Request node, hand-built XML, and a parser that breaks the first time a country is offline.

So the check either doesn’t happen, or it happens once by hand at the wrong end of the month.

The Solution

I published a community node that makes VAT validation an ordinary step in a workflow. Two resources, four operations, and a deliberate split between what costs nothing and what costs a request:

VAT Number – Check Format runs entirely offline against the country’s pattern: no key, no network call, no quota. Validate verifies the number against the live VIES register through vatnode and returns validity, the registered company name and address, the registration date, and the VIES consultation number when the account has a requester VAT configured.

VAT Rate – Get returns the standard, reduced, super-reduced and parking rates for one country plus its VAT number format; Get Many returns the same for every covered country as one n8n item each. Both are free and need no account.

The intended shape of a workflow is that order: Check Format filters typos for nothing, Validate confirms only the survivors against VIES, and an IF node downstream routes on valid while the consultation number is written to the customer record as evidence. Nobody spends quota on a mistyped number.

The node is also declared usableAsTool, so an n8n AI agent can call VAT validation directly as one of its tools – the same capability the MCP server gives Claude and Cursor, delivered inside the automation platform instead of the desktop assistant.

Results

MetricValue
Release[email protected], 5 August 2026
StatusVerified by n8n – live on n8n Cloud
Surface2 resources, 4 operations
Free of quota3 of 4 operations – format check and both rate ops
Source251 lines node + 64 lines credential, TypeScript
CountriesEU-27 + XI via VIES, ~45 for rate lookup
CI secrets0 – npm Trusted Publishing via OIDC
ProvenanceSigstore-signed, publicly auditable per release
LicenseMIT

Published on npm as n8n-nodes-vatnode, and verified by n8n on 6 August 2026 – which means it is not merely installable but shipped with n8n Cloud, where a user searches for it on the canvas and drags it into a workflow like any first-party node. Every subsequent npm version goes through the same review before it reaches that channel.

This is the automation-platform surface of the same VAT stack that also ships as a SaaS API, an open rate dataset, an MCP server and a WooCommerce plugin. Each one meets a different person where they already work: the developer in code, the AI assistant in chat, the shop owner in WordPress, and here the operations lead in a workflow canvas.

Under the Hood

For the technically curious, here is how the core pieces are built.

A credential test that costs nothing

n8n calls the credential test whenever someone saves a key, and a naive implementation validates a real VAT number – which means every save spends a request from the user’s monthly quota, and a user fiddling with settings burns their free plan before running a single workflow.

The test sends the reserved XX0000001 number instead. No country uses the XX prefix, so the API rejects it on format before it ever reaches VIES: the request proves the key authenticates and stops there. A working key and a rejected key are still perfectly distinguishable – only the quota is spared.

One bad item must not kill the batch

An n8n node receives a batch of items, and in a VAT workflow the batch is a customer list where one row will have a typo. The loop isolates failures per item and honours the user’s continueOnFail setting, so a bad row becomes an item with an error field rather than a dead execution:

} catch (error) {
  if (this.continueOnFail()) {
    returnData.push({ json: { error: (error as Error).message }, pairedItem: { item: i } });
    continue;
  }
  // Input problems are ours, not the API's — keep them out of NodeApiError.
  if (error instanceof NodeOperationError) {
    throw new NodeOperationError(this.getNode(), error.message, { itemIndex: i });
  }
  throw new NodeApiError(this.getNode(), error as JsonObject, { itemIndex: i });
}

The distinction between NodeOperationError and NodeApiError matters in the UI: the first tells the user their input is wrong, the second tells them the upstream failed. Collapsing both into one error type sends people debugging their credentials when they actually typed an empty VAT number.

Every output item also carries pairedItem, so n8n can trace each result back to the row it came from – without it the ‘item linking’ breaks and downstream nodes lose the connection to the original customer.

The parameter typed as a string that isn’t one

An n8n parameter declared type: 'string' is not guaranteed to arrive as a string. Users fill these with expressions, and {{ $json.vatId }} on an item that has no vatId resolves to undefined. Calling .toUpperCase() on it crashes the node with a stack trace instead of a readable message:

function toStringParam(value: unknown): string {
  return value === undefined || value === null ? "" : String(value);
}

Coerced to an empty string, it flows into the same explicit emptiness check that produces ‘The VAT number is empty’ – a message the person who wrote the expression can act on.

Country patterns generated at build time

The format check needs every country’s VAT pattern, and hardcoding 45 regexes into the node makes them a second source of truth that quietly drifts from the API. A build-time script generates countries.generated.ts from the same open eu-vat-rates-data package the rest of the stack uses, so a pattern is corrected in one place and reaches the node on the next release.

One quirk survives the generation on purpose: VIES writes Greece as EL, while the rate endpoint keys it as GR. Both are accepted on input and mapped where needed – a user should not have to know which EU service decided which.

Iurii RoguliaAvailable

Need something similar?

I build custom solutions – from APIs to full products. Let’s talk about your project.

View all projects

Related projects

vatnode.dev mcp – Official MCP Server for EU VAT Validation
vatnode.dev mcp – Official MCP Server for EU VAT Validation
May 20, 2026
vatnode.dev mcp – Official MCP Server for EU VAT Validation

Open-source MCP server that lets Claude Desktop, Cursor and other MCP clients validate EU VAT numbers and look up rates directly in chat.

Stack

TypeScriptNode.js

Libraries

Zod

Services

vatnode API

Topics

MCPAI ToolingDeveloper ToolsOpen SourceTax/VAT
polytypo.dev – Locale-Correct Typography Engine and Spec
polytypo.dev – Locale-Correct Typography Engine and Spec
September 8, 2026
polytypo.dev – Locale-Correct Typography Engine and Spec

Open-source spec and engine that turns straight quotes, hyphens and three dots into the correct curly quotes, dashes, ellipses and no-break spaces for 10

Stack

TypeScriptJavaScriptPythonPHPGoRuby

Libraries

micromarkparse5tree-sitter

Services

npmPyPIPackagistRubyGemsGitHub ActionsGitHub Pages

Topics

Open SourceDeveloper Toolsi18nTypographyConformance TestingProperty-Based Testing

Related posts

Publishing One Package to Five Registries with GitHub Actions
March 27, 2026· 10 min
Publishing One Package to Five Registries with GitHub Actions

How to publish one dataset to npm, PyPI, Go Module, RubyGems, and Packagist automatically with GitHub Actions – architecture, versioning, and per-ecosystem

Stack

TypeScriptPythonPHPGoRuby

Services

GitHub ActionsnpmPyPIPackagistRubyGems

Topics

Open SourceTax/VATAutomation
Building an MCP Server for VAT Validation: Why It’s Two Tools, Not One
September 18, 2026· 9 min
Building an MCP Server for VAT Validation: Why It’s Two Tools, Not One

Building the vatnode MCP server meant deciding whether format-checking and live VIES validation should be one tool or two.

Stack

TypeScriptNode.js

Services

vatnode API

Topics

MCPAPI DesignDeveloper ToolsAI Tooling