EU VAT Validation
Live EU VAT validation for invoicing, onboarding and compliance workflows. The number is checked against VIES — the European Commission's official cross-border VAT information exchange system — which queries the member state's real register: a valid answer means the trader is registered for intra-EU transactions RIGHT NOW, and where the member state publishes them you also get the registered trader name and address to match against what your counterparty claimed. Accepts the number in any common shape ('RO12345678', 'ro 123-456.78', or country and number as separate fields); Greece's EL prefix and Northern Ireland's XI are handled. Member-state outages (a VIES reality) are reported as retryable errors, never as false negatives, and an invalid answer explains that some states have domestic-only registrations that VIES does not cover. Reverse-charge B2B invoicing inside the EU requires exactly this check — agents issuing invoices should run it before every new counterparty.
Call with x402
1. Send the request. 2. Receive 402 with accepts[]. 3. Sign the payment and retry with the X-PAYMENT header.
curl -X POST https://agentbit.app/v1/compliance/vat \
-H 'Content-Type: application/json' \
-d '{"vat_number":"RO14399840"}'
Input schema
{
"type": "object",
"properties": {
"vat_number": {
"type": "string",
"description": "VAT number, with or without the country prefix, e.g. RO12345678"
},
"country": {
"type": "string",
"description": "Two-letter member state code if not included in vat_number (EL for Greece, XI for Northern Ireland)"
}
},
"required": [
"vat_number"
]
}Output schema
{
"type": "object",
"properties": {
"country": {
"type": "string"
},
"vat_number": {
"type": "string"
},
"full_vat_number": {
"type": "string"
},
"valid": {
"type": "boolean"
},
"trader_name": {
"type": [
"string",
"null"
]
},
"trader_address": {
"type": [
"string",
"null"
]
},
"checked_at": {
"type": "string"
},
"source": {
"type": "string"
},
"note": {
"type": "string"
}
}
}Code examples
// JavaScript (x402-fetch)
import { wrapFetchWithPayment } from "x402-fetch";
const fetchWithPay = wrapFetchWithPayment(fetch, wallet);
const r = await fetchWithPay("https://agentbit.app/v1/compliance/vat", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({"vat_number":"RO14399840"})
});
console.log(await r.json());
# Python (x402 client)
from x402.clients.requests import x402_requests
s = x402_requests(account)
r = s.post("https://agentbit.app/v1/compliance/vat",
json={"vat_number":"RO14399840"})
print(r.json())
// PHP
$r = Http::withHeaders(['X-PAYMENT' => $signedPayment])
->post('https://agentbit.app/v1/compliance/vat',
array (
'vat_number' => 'RO14399840',
));
$data = $r->json();