Home / Use cases / Custom

Custom

Build a tax compliance platform with VAT validation

Integrate EU VAT validation as a core module in a tax compliance SaaS platform. Includes webhook notifications, audit logging, and multi-tenant architecture patterns.

A tax compliance SaaS platform needs VAT validation as a foundational capability that multiple product features — invoicing, billing, KYB, seller onboarding — can consume without each embedding its own HTTP client and caching logic. The right architecture is a dedicated VAT validation microservice or module that exposes an internal API, manages its own cache layer, and publishes domain events (e.g. VATValidated, VATInvalidated, VATStatusChanged) that other modules subscribe to.

Multi-tenancy introduces additional complexity: each tenant's VAT validation requests must be isolated so one tenant's cache cannot bleed into another's, API key quotas must be enforced per-tenant if you are re-selling TaxID capacity, and audit logs must be partitioned by tenant_id for data-residency compliance. Structure your internal validation service to accept a tenant_id alongside every request and prefix all cache keys and audit table rows with the tenant scope.

Webhook notifications are valuable when VAT numbers change status — a business can deregister from VIES, causing a previously valid customer to become invalid. Implement a daily re-validation job for all customers with status: 'active' (TaxID's 24-hour cache window means once-daily calls are the minimum meaningful frequency) and fire a webhook to the tenant's configured endpoint when a status change is detected. Include the old_status, new_status, company_name, request_id, and timestamp in the webhook payload for downstream automation.

Implementation steps

  1. 1

    Design VAT validation microservice

    Create a standalone service (or a well-bounded module) with a single public method: validate(tenantId, country, vatNumber): Promise<VATResult>. Internally, check the tenant-scoped cache first (key: {tenantId}:vat:{country}:{vat}), call GET /api/v1/validate/:country/:vat on a miss, store the response with the appropriate TTL (86400 s for active, 3600 s for invalid), and emit a domain event via your message bus. This design allows the service to be independently scaled and replaced without touching callers.

  2. 2

    Implement webhook for real-time updates

    Allow tenants to register a webhook URL in their platform settings. When your daily re-validation job detects a status change (e.g. a previously active number returns invalid), POST a signed webhook payload to the tenant's URL with fields: event: 'vat.status_changed', old_status, new_status, country, vat_number, company_name, request_id, and occurred_at. Sign the payload with HMAC-SHA256 using a per-tenant secret so tenants can verify the webhook's authenticity before acting on it.

  3. 3

    Store validation history per customer

    Maintain a vat_validation_history table with columns: id, tenant_id, customer_id, country_code, vat_number, status, company_name, company_address, request_id, source ('api_call' | 'cache' | 'background_revalidation'), and validated_at. Never overwrite previous rows — append a new row on every validation event. This append-only log lets you reconstruct the exact validation status at any historical point in time, which is essential for defending reverse-charge decisions during a tax audit.

  4. 4

    Build compliance dashboard with audit trail

    Expose a compliance dashboard screen that shows each customer's current VAT status, the date of last validation, the source (live VIES vs cached), and the full history of status changes. Add a manual re-validate button that calls your microservice with source: 'manual' and refreshes the UI. Include a CSV export of the audit trail filtered by date range so tenants can produce the evidence bundle required by their local tax authority without needing to query your database directly.

Code example

Node.js

const res = await fetch(
  'http://localhost:3000/api/v1/validate/DE/DE123456789',
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const { valid, status, company_name, company_address } = await res.json();

if (valid) {
  console.log(`Valid EU business: ${company_name}`);
} else if (status === 'service_unavailable') {
  // VIES is temporarily down — retry or allow with manual check
  console.log('VIES unavailable — check back in a few minutes');
} else {
  console.log('Invalid VAT number — charge local tax rate');
}

Python

import requests

res = requests.get(
    "http://localhost:3000/api/v1/validate/DE/DE123456789",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = res.json()

if data["valid"]:
    print(f"Valid: {data['company_name']}")
elif data["status"] == "service_unavailable":
    print("VIES temporarily unavailable")
else:
    print("Invalid VAT number")

API response

The TaxID API returns a consistent JSON response for every validation request:

200 OK (active)valid
{
  "valid": true,
  "status": "active",
  "country_code": "DE",
  "vat_number": "123456789",
  "company_name": "Example GmbH",
  "company_address": "Musterstraße 1, 10115 Berlin",
  "request_date": "2026-05-10T00:00:00.000Z",
  "cached": false,
  "request_id": "req_01j..."
}

Error handling

The API uses a consistent Stripe-style error format. Always handle service_unavailable separately — VIES has occasional downtime and you should not reject valid customers during outages.

active

VAT number is valid and the business is registered

invalid

VAT number format is wrong or not registered in VIES

service_unavailable

VIES or the national system is temporarily down — retry later

Further reading

Evaluating EU VAT APIs? Compare TaxID with:

Ready to implement?

Get your free API key and start validating EU VAT numbers today.

Get free API key

Related use cases

EU VAT compliance for SaaS billing

Handle EU VAT for SaaS subscriptions. Validate customer VAT numbers at signup, determine B2B vs B2C ...

DAC7 marketplace seller VAT verification

Verify seller VAT numbers during marketplace onboarding for DAC7 compliance. EU platforms must colle...

Bulk VAT number validation via CSV import

Validate hundreds of EU VAT numbers in batch using parallel API requests. Ideal for CRM data cleansi...