Skip to content
Holits

Platform Engineering

Company Intel

An EU VAT validation and company-registry API built around the failure modes of VIES, not just its happy path — circuit-broken per country, with a legally usable audit trail on every check.

By Holits

The problem

EU VAT validation looks like a solved problem — VIES is a free, official government endpoint. It just isn't reliable per member state: it goes down, rate-limits aggressively, and offers no fallback of its own. A B2B platform doing reverse-charge validation on every invoice needs an answer even when VIES doesn't have one, and needs proof of the check for the tax authority later, not just a boolean.

The second half of the problem is company data itself: VAT numbers, national company registration numbers and trade-registry identifiers are genuinely distinct identifiers a single company can hold at once, sourced from incompatible national registries with no shared schema.

The approach

The product isn't the VAT lookup — it's what happens around it. A per-country circuit breaker sits in front of VIES: three failures trip it open, a cooldown period gates recovery attempts, and while it's open the service serves the last known-good response instead of an error, with the response labelled so a caller can distinguish a live check from a cached one. A ?live=true bypass exists as an explicit, quota-weighted path for callers who need a compliance- grade check regardless of cache state.

Every VAT check — live or cached — returns VIES's own consultation number, the piece that makes a validation legally usable as proof to a tax authority rather than just an internal boolean.

Company data behind one identifier

Registry ingestion runs as scheduled ETL jobs per country — VIES on demand, UK Companies House daily, French INSEE Sirene weekly (a multi-million-record bulk load), Romanian ONRC monthly, with several more national adapters in varying states of coverage. Every record resolves to a canonical ID derived from a hash of country and registration number, so the same company arriving from two different national sources still lands on one row. Validation failures during ingestion go to a dead-letter table instead of failing the whole job, and distributed locks stop overlapping runs from double-processing a source.

Billing kept out of the request path

Billing runs as its own service, with its own database access and its own Stripe integration — the core API never talks to Stripe directly, and the browser never talks to billing directly either; everything routes through an internally authenticated call. The separation means a billing-provider outage degrades checkout, not VAT validation.

Design decisions worth noting

  • Scope discipline on day one. The first version deliberately ingested one country's registry, not two at once — the stated reasoning being that ingesting two national registries simultaneously was the single biggest schedule risk in the initial build.
  • No SLA promises the system can't back up. Uptime claims are scoped to what the service itself controls, separated explicitly from VIES's own availability, rather than a single blended number with no load-test evidence behind it.
  • Account deletion ordering matters. A subscription must be cancelled with the billing provider before local billing records are purged — reversing that order left customers who no longer existed locally still being billed externally, a real support-and-money bug rather than a cosmetic one.
  • Plan resolution by ID, not by label. An early version fell back to matching a Stripe price by its human-readable nickname when a lookup missed — which meant a price's nickname, not its ID, could accidentally grant plan access. Plan resolution now requires the exact price ID.

Case study

See this in production: Building a resilient compliance API on top of an unreliable government service.

Availability

Private. Built and operated in-house; not distributed under an open licence.