EU VAT validation in Deno
Validate EU VAT numbers in Deno using the built-in fetch API and TypeScript. Deployable to Deno Deploy with zero configuration — no npm install, no package.json needed.
Deno's built-in fetch API, first-class TypeScript support, and permission-based security model make it an excellent runtime for calling external APIs like TaxID. The permission system requires --allow-net to make outbound HTTP requests and --allow-env to read environment variables, which means the validation function cannot silently make network calls without explicit operator approval — a useful security property for compliance-sensitive applications.
Deno Deploy runs the same code globally on V8 isolates with sub-millisecond cold starts, making it a viable alternative to Cloudflare Workers for edge-deployed VAT validation. The deployment is triggered by a git push with no Docker, no YAML manifests, and no build step — the TypeScript source is executed directly. Environment variables (including the TaxID API key) are configured in the Deno Deploy dashboard and injected via Deno.env.get('TAXID_API_KEY').
TypeScript interfaces defined in Deno are structurally typed, so the VATResult interface doubles as documentation and a compile-time guard against typos in field access. Because Deno has no node_modules directory and no package.json, dependency management for this use case is entirely optional — the standard library's fetch and JSON.parse are the only tools needed.
Implementation steps
- 1
Use Deno's built-in fetch — no imports needed for HTTP
Deno's global fetch is available in all contexts without any import. Define an async function validateVAT(country: string, vat: string): Promise<VATResult> that calls fetch(`https://api.taxid.pro/v1/validate/${country}/${vat}`, { headers: { Authorization: `Bearer ${Deno.env.get('TAXID_API_KEY')}` } }). The function is immediately usable in any Deno script without installing dependencies or modifying a package manifest.
- 2
Load the API key from Deno.env or a .env file
In local development, create a .env file with TAXID_API_KEY=your_key and load it using Deno's built-in --env flag (deno run --env --allow-net --allow-env validate.ts). In Deno Deploy, set the environment variable in the project dashboard. Access it with Deno.env.get('TAXID_API_KEY') and throw an error at startup if it is undefined rather than silently sending unauthenticated requests.
- 3
Define a TypeScript interface for the VATResult response
Declare: interface VATResult { valid: boolean; status: 'active' | 'invalid' | 'service_unavailable'; company_name: string | null; company_address: string | null; cached: boolean; request_id: string; }. Cast the parsed JSON to this interface with const result = await response.json() as VATResult. While this is a type assertion rather than runtime validation, combining it with a runtime check on result.status being one of the three known values adds a safety net against unexpected API changes.
- 4
Run with --allow-net --allow-env or deploy to Deno Deploy
Execute locally with deno run --allow-net=api.taxid.pro --allow-env=TAXID_API_KEY validate.ts — scoping --allow-net to the specific domain restricts the script from making outbound calls to any other host, which is a stronger security posture than blanket --allow-net. For Deno Deploy, push the file to GitHub and connect the repository in the Deno Deploy dashboard; the runtime permissions are automatically granted to the deployed isolate.
Code example
Deno (TS)
// deno run --allow-net --allow-env validate_vat.ts
// Deploy to Deno Deploy — no npm install, no config
interface VATResult {
valid: boolean;
status: string;
company_name?: string;
company_address?: string;
}
async function validateVAT(
country: string,
vatNumber: string
): Promise<VATResult> {
const res = await fetch(
`http://localhost:3000/api/v1/validate/${country}/${vatNumber}`,
{ headers: { Authorization: `Bearer ${Deno.env.get("TAXID_API_KEY")}` } }
);
return res.json() as Promise<VATResult>;
}
const result = await validateVAT("DE", "DE123456789");
if (result.valid) {
console.log(`Valid EU business: ${result.company_name}`);
} else if (result.status === "service_unavailable") {
console.warn("VIES temporarily unavailable — retry later");
} else {
console.log("Invalid VAT number");
}cURL
curl "http://localhost:3000/api/v1/validate/DE/DE123456789" \
-H "Authorization: Bearer $TAXID_API_KEY"
# {
# "valid": true,
# "status": "active",
# "company_name": "Example GmbH",
# "company_address": "Musterstraße 1, 10115 Berlin",
# "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…
VAT for Developers: The Complete 2026 Implementation Guide
VAT is a consumption tax collected at each stage of the supply chain. For developers, this means implementing rate looku…
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...