The TaxID API validates VAT numbers, ABNs, and other tax IDs across 31+ countries via a single REST endpoint. This page is the quick-reference guide for developers: what the API accepts, what it returns, and how to handle every possible response. For step-by-step language-specific tutorials, see the Node.js, Python, PHP, and React guides linked at the bottom.
Authentication
All requests require an API key passed in the `Authorization` header. Get your key from the dashboard after signing up. There are two key types: live keys (`vat_live_...`) for production requests and test keys (`vat_test_...`) for development — test keys return predictable responses without consuming quota.
# Always pass the key in the Authorization header
curl -H "Authorization: Bearer vat_live_xxxxxxxxxxxxxxxx" \
https://taxid.dev/api/v1/validate/DE/DE123456789
# Never include the key in the URL — it would appear in server logsValidate Endpoint
GET https://taxid.dev/api/v1/validate/{country}/{vat_number}
# {country} — two-letter country prefix (e.g. DE, GB, AU)
# {vat_number} — the full VAT number including the country prefix
# Example:
GET https://taxid.dev/api/v1/validate/DE/DE123456789Response Schema
| Field | Type | Description |
|---|---|---|
| valid | boolean | Shorthand: true when status === 'active' |
| status | string | active | inactive | format_invalid | service_unavailable |
| vat | string | Normalised VAT number as validated |
| country_code | string | Two-letter country prefix |
| company_name | string | null | Registered company name (from national registry) |
| address | string | null | Registered address (from national registry) |
| cached | boolean | true if served from TaxID response cache |
| request_id | string | Unique request ID — use as audit reference |
Status Code Reference
| Status | HTTP | Meaning | Correct action |
|---|---|---|---|
| active | 200 | VAT number is valid and currently registered | Apply zero-rate / reverse charge |
| inactive | 200 | VAT number exists but registration has lapsed | Charge standard VAT; reject exemption claim |
| format_invalid | 200 | Input does not match the country's VAT format | Show format hint to user; do not retry |
| service_unavailable | 200 | National registry temporarily offline | Charge standard VAT; re-validate later |
Note
All four statuses return HTTP 200. The `status` field in the body drives your application logic, not the HTTP status code. A 4xx or 5xx response indicates an API-level error (invalid key, malformed request, rate limit exceeded).
Quick-Start Code
async function validateVat(vatNumber: string) {
const country = vatNumber.slice(0, 2).toUpperCase();
const vat = vatNumber.replace(/\s/g, '').toUpperCase();
const res = await fetch(
`https://taxid.dev/api/v1/validate/${country}/${vat}`,
{ headers: { Authorization: `Bearer ${process.env.TAXID_API_KEY}` } }
);
if (!res.ok) throw new Error(`API error: ${res.status}`);
return res.json();
}import os, requests
def validate_vat(vat_number: str) -> dict:
country = vat_number[:2].upper()
vat = vat_number.replace(' ', '').upper()
resp = requests.get(
f'https://taxid.dev/api/v1/validate/{country}/{vat}',
headers={'Authorization': f'Bearer {os.environ["TAXID_API_KEY"]}'},
timeout=5,
)
resp.raise_for_status()
return resp.json()function validateVat(string $vatNumber): array {
$country = strtoupper(substr($vatNumber, 0, 2));
$vat = strtoupper(str_replace(' ', '', $vatNumber));
$ch = curl_init("https://taxid.dev/api/v1/validate/{$country}/{$vat}");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('TAXID_API_KEY')],
CURLOPT_TIMEOUT => 5,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
return $response;
}Country Coverage
The API covers 31+ countries. EU countries are validated via VIES; non-EU countries via their respective national registries.
- →EU (27 countries): AT, BE, BG, CY, CZ, DE, DK, EE, EL/GR, ES, FI, FR, HR, HU, IE, IT, LT, LU, LV, MT, NL, PL, PT, RO, SE, SI, SK
- →United Kingdom: GB (HMRC) and XI (Northern Ireland)
- →Australia: AU (Australian Business Register)
- →Norway: NO (Brønnøysund Register Centre)
- →Switzerland: CH (Federal Tax Administration UID)
Rate Limits and Quotas
| Plan | Monthly validations | Requests/second |
|---|---|---|
| Free | 100 | 2 |
| Starter | 1,000 | 10 |
| Growth | 10,000 | 30 |
| Scale | 100,000+ | Custom |
When you exceed the rate limit, the API returns HTTP 429. Cache results for 24 hours to reduce API calls — the TaxID API already caches at the infrastructure level, but caching in your own application reduces latency and protects your quota.
Related guides
Start validating EU VAT numbers
Free plan — 100 validations/month. No credit card required.