Async VAT Validation: Webhooks and Batch Processing
Sync VAT validation works for most use cases, but it breaks down in three scenarios: high-latency checkout flows, bulk revalidation of existing customers, and VIES downtime. Async validation solves all three. Submit the request, get an immediate 202, and receive the result via webhook.
When sync validation is not enough
Checkout latency
In our monitoring, VIES takes 1 to 3 seconds per lookup depending on the member state, with some countries consistently at the slow end. In a checkout flow, that delay is visible to the customer. Async validation lets you accept the order immediately and process the VAT check in the background.
Bulk revalidation
If you have 500+ B2B customers, revalidating their VAT numbers quarterly means 500+ sequential API calls with rate limiting delays. With async batch validation, you submit all numbers in a single request (up to 200 for Pro, 1,000 for Business) and receive one webhook when all results are ready.
VIES downtime resilience
When a country's VIES service is down, sync validation fails with a 503 error. Async validation moves that failure handling out of your request path: Avatcado retries VIES briefly during the lookup and falls back to a recent cached result when one exists. If the registry is down and there is no cached result, you receive a validation.failed webhook and the validation is refunded to your quota, so you can resubmit once the service recovers.
How async validation works
Single async validation
POST one number to /v1/validate/async, get a 202 with a request_id, and receive a validation.completed or validation.failed webhook when processing finishes.
Batch async validation
POST an array of numbers to /v1/validate/async/batch. Avatcado validates each format immediately. Invalid formats are rejected in the 202 response (never queued). Valid items are processed in the background and a single batch.completed webhook is delivered when all items finish.
Example: submitting a batch
const response = await fetch("https://api.avatcado.com/v1/validate/async/batch", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer avat_live_your_api_key",
},
body: JSON.stringify({
vat_numbers: ["DE123456789", "NL987654321B01", "FR12345678901"],
cache: true,
}),
});
const { data } = await response.json();
// data.batch_id: "550e8400-..."
// data.accepted: 3
// data.rejected: []
// data.status: "pending"
// Results arrive via webhook when processing completesHandling webhook deliveries
Every webhook is signed with HMAC-SHA256 using your signing secret. Always verify the signature before processing the payload.
Webhook handler example
import { createHmac } from "crypto";
// Express / Node.js example
app.post("/webhooks/avatcado", (req, res) => {
const signature = req.headers["x-avatcado-signature"];
const timestamp = req.headers["x-avatcado-timestamp"];
const body = req.body; // raw string
// Verify signature
const expected = createHmac("sha256", process.env.AVATCADO_WEBHOOK_SECRET)
.update(`${timestamp}.${body}`)
.digest("hex");
if (signature !== `sha256=${expected}`) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(body);
switch (event.event) {
case "validation.completed":
// event.data contains the validation result
updateCustomerVatStatus(event.data.vat_number, event.data.valid);
break;
case "batch.completed":
// event.data.results contains all items
for (const item of event.data.results) {
if ("data" in item) {
updateCustomerVatStatus(item.data.vat_number, item.data.valid);
}
}
break;
case "validation.failed":
// event.error has the failure reason (event.data contains the vat_number)
flagForManualReview(event.data.vat_number, event.error);
break;
}
res.status(200).send("OK");
});Use case: quarterly customer revalidation
Companies with hundreds of B2B customers should revalidate VAT numbers periodically. VAT registrations can be revoked, businesses can close, and numbers can become invalid at any time. Quarterly revalidation is a common practice for compliance.
With async batch validation, the process is simple:
- Query your database for all active customer VAT numbers
- Submit them in a single batch request (up to 200 or 1,000 depending on your plan)
- Receive a
batch.completedwebhook with all results - Update your records and flag any newly invalid numbers for review
// Quarterly revalidation script
const customers = await db.query("SELECT vat_number FROM customers WHERE active = true");
const vatNumbers = customers.map((c) => c.vat_number);
const response = await fetch("https://api.avatcado.com/v1/validate/async/batch", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.AVATCADO_API_KEY}`,
},
body: JSON.stringify({ vat_numbers: vatNumbers }),
});
const { data } = await response.json();
console.log(`Batch ${data.batch_id}: ${data.accepted} accepted, ${data.rejected.length} rejected`);
// Results will arrive via webhookGet started
Async validation and webhooks are available on Pro (starting at €29/month) and Business plans.
- Create a free account and upgrade to Pro
- Configure your webhook URL in the dashboard
- Read the webhook documentation for signature verification and event payload details
- Read the async validation documentation for endpoint details and error handling
Frequently asked questions
What happens if VIES is down when I submit an async request?
If a cached result exists for the number, Avatcado serves it from cache (marked stale if it is past the TTL) and delivers it via webhook as usual. If the upstream registry is down and no cached result exists, the request fails fast: you receive a validation.failed webhook and the validation is refunded to your quota, so you can resubmit once the registry recovers.
Do async validations count against my monthly quota?
Yes. Each VAT number is counted once when the request is accepted (the 202 response), not when the result is delivered.
Can I mix sync and async validation?
Yes. The sync endpoints (GET /v1/validate, POST /v1/validate/batch) continue to work as before. Use sync for real-time validation and async for bulk processing or when you want resilience against downtime.
What is the maximum batch size for async?
Pro: 200 items per batch. Business: 1,000 items per batch.
Sources
- Avatcado async validation documentation Avatcado, accessed August 13, 2026
- Avatcado webhooks documentation Avatcado, accessed August 13, 2026
- VIES on-the-Web European Commission, accessed August 13, 2026