Home / Use cases / Cloudflare Workers
EU VAT validation in Cloudflare Workers
Run EU VAT validation at the Cloudflare edge with Workers. Store your API key as a Worker secret, validate VAT numbers globally with no cold starts, and cache results at the edge.
Cloudflare Workers run JavaScript/TypeScript at the network edge across 300+ data centres worldwide, meaning VAT validation requests are handled within milliseconds of the end user regardless of their location in the EU. Workers have no cold starts (unlike AWS Lambda or Vercel Functions), making them ideal for latency-sensitive checkout flows where VAT validation is in the critical path.
The TaxID API is called from inside the Worker's fetch handler using the standard global fetch function, with the API key injected via env.TAXID_API_KEY (a Worker secret stored with wrangler secret put TAXID_API_KEY). The Worker can also serve as a reverse-proxy caching layer: use the Cloudflare Cache API (caches.default) to store validation results at the edge for 24 hours for active numbers, reducing round-trips to the TaxID origin for repeat lookups from the same edge node.
Workers integrate naturally with Cloudflare D1 (SQLite at the edge) or KV (key-value store) for audit logging. Storing each validation result in KV with a composite key of {country}:{vat} and a TTL matching TaxID's cache window means that multiple Workers across different edge nodes share the same cached results, maximising cache hit rates across a globally distributed checkout infrastructure.
Implementation steps
- 1
Create a Worker with the standard fetch handler
Initialise the project with npm create cloudflare@latest and choose the 'Hello World' TypeScript template. The Worker's entry point is export default { async fetch(request: Request, env: Env): Promise<Response> { ... } }. Define the Env interface with TAXID_API_KEY: string so TypeScript enforces that the secret binding is declared in wrangler.toml before the Worker is deployed.
- 2
Store TAXID_API_KEY as a Worker secret via wrangler secret put
Run npx wrangler secret put TAXID_API_KEY in your terminal and paste the API key when prompted. This encrypts the key at rest in Cloudflare's secret store and injects it into env.TAXID_API_KEY at runtime without it appearing in wrangler.toml or source control. Never use a plaintext [vars] entry in wrangler.toml for the API key — vars values are visible in the Cloudflare dashboard to any team member with Workers access.
- 3
Forward validation requests to the TaxID API with env.TAXID_API_KEY
Inside the fetch handler, extract country and vat from the request URL path or query string, then call: const res = await fetch(`https://api.taxid.pro/v1/validate/${country}/${vat}`, { headers: { Authorization: `Bearer ${env.TAXID_API_KEY}` } }). Parse the JSON response and inspect result.status to determine the validation outcome before returning a response to the caller.
- 4
Return the JSON response with Cache-Control headers for valid results
For status: 'active' responses, set Cache-Control: public, max-age=86400 on the Worker's outbound response so Cloudflare's edge cache stores the result for 24 hours. Use the Cache API (const cache = caches.default; await cache.put(request, response.clone())) for fine-grained control. For invalid and service_unavailable responses, set Cache-Control: no-store to prevent negative results from persisting beyond the current request.
Code example
Workers (JS)
// Store your API key as a Worker secret:
// $ wrangler secret put TAXID_API_KEY
export default {
async fetch(request, env) {
const { searchParams } = new URL(request.url);
const country = searchParams.get('country');
const vat = searchParams.get('vat');
if (!country || !vat) {
return Response.json({ error: 'country and vat required' }, { status: 400 });
}
const res = await fetch(
`http://localhost:3000/api/v1/validate/${country}/${vat}`,
{ headers: { 'Authorization': `Bearer ${env.TAXID_API_KEY}` } }
);
const result = await res.json();
// Cache valid results at the Cloudflare edge for 1 hour
const ttl = result.valid ? 3600 : 0;
return Response.json(result, {
headers: { 'Cache-Control': ttl ? `max-age=${ttl}` : 'no-store' }
});
}
};cURL
# Test locally with wrangler:
# wrangler dev — then curl "http://localhost:8787?country=DE&vat=DE123456789"
# Or call the TaxID API directly:
curl "http://localhost:3000/api/v1/validate/DE/DE123456789" \
-H "Authorization: Bearer $TAXID_API_KEY"
# {
# "valid": true,
# "status": "active",
# "company_name": "Example GmbH",
# "cached": false
# }API response
The TaxID API returns a consistent JSON response for every validation request:
{
"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.
activeVAT number is valid and the business is registered
invalidVAT number format is wrong or not registered in VIES
service_unavailableVIES or the national system is temporarily down — retry later
Further reading
EU VAT Number Validation: The Complete Developer Guide (2026)
VIES is SOAP-based, unreliable, and has no caching. This guide explains how EU VAT validation works end-to-end, how to h…
How to Use a VAT Rates API: Developer Integration Guide
A VAT rates API lets you fetch current EU VAT rates programmatically instead of hardcoding rate tables. This guide cover…
Evaluating EU VAT APIs? Compare TaxID vs Vatstack, Vatlayer, Avalara →
Related use cases
Validate EU VAT numbers in Stripe Checkout
Add EU VAT validation to your Stripe checkout flow. Verify customer VAT numbers server-side before a...
UK VAT validation in Shopify B2B
Validate UK VAT numbers for B2B customers in Shopify. Required under UK Making Tax Digital rules for...
WooCommerce Spain NIF/CIF validation
Validate Spanish NIF and CIF numbers in WooCommerce checkout. Automatically apply B2B tax exemptions...