VIES VAT Validation API

Validate European VAT numbers in real-time against the official EU VIES (VAT Information Exchange System) service. Returns company name and address from official government databases across all EU member states.

Real-time EU Validation

Validates VAT numbers directly against the European Commission's VIES service for all 27 EU member states.

Company Details Included

Returns company name and address from official EU records when available.

Base URL

https://api.clients.lv/api/vies

Authentication & Permissions

All API endpoints require authentication using Bearer tokens with the following permission:

Required Permission

vies:read - Required for all VIES Validation API access

Provides access to real-time EU VIES VAT number validation with company data retrieval.

Authentication Example

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     -X POST https://api.clients.lv/api/vies/validate \
     -d '{"vat_number": "LV40203029397"}'

API Endpoints

POST /api/vies/validate

Validate a VAT number against the EU VIES service. Returns validation status, company name, and address.

Request Body

Parameter Type Required Description
vat_number string Yes VAT number with country prefix (e.g., DE123456789, LV40203029397)

Example Requests

Validate a Latvian VAT number:

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -X POST "https://api.clients.lv/api/vies/validate" \
     -d '{"vat_number": "LV40203029397"}'

Validate a German VAT number:

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -X POST "https://api.clients.lv/api/vies/validate" \
     -d '{"vat_number": "DE123456789"}'

Response Examples

Valid VAT number:

{
  "valid": true,
  "vat_number": "DE123456789",
  "country": "DE",
  "format_valid": true,
  "vies_available": true,
  "company_name": "EXAMPLE GMBH",
  "company_address": "MUSTERSTRASSE 1\n12345 BERLIN",
  "request_date": "2026-03-31",
  "cached": false,
  "error": null
}

Invalid VAT number:

{
  "valid": false,
  "vat_number": "DE000000000",
  "country": "DE",
  "format_valid": true,
  "vies_available": true,
  "company_name": null,
  "company_address": null,
  "request_date": "2026-03-31",
  "cached": false,
  "error": null
}

Invalid format (no VIES call made):

{
  "valid": false,
  "vat_number": "XX12345",
  "country": "XX",
  "format_valid": false,
  "vies_available": null,
  "company_name": null,
  "company_address": null,
  "request_date": null,
  "cached": false,
  "error": "Unknown or unsupported country code: XX"
}

VIES service unavailable (HTTP 503):

{
  "valid": false,
  "vat_number": "DE123456789",
  "country": "DE",
  "format_valid": true,
  "vies_available": false,
  "company_name": null,
  "company_address": null,
  "request_date": null,
  "cached": false,
  "error": "VIES service is currently unavailable. Please try again later."
}
GET /api/vies/stats

Get VIES validation usage statistics including cache performance and per-country breakdown.

Example Request

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
     "https://api.clients.lv/api/vies/stats"

Response Example

{
  "total_requests": 1523,
  "cache_hits": 892,
  "api_calls": 631,
  "api_errors": 12,
  "valid_results": 1104,
  "invalid_results": 407,
  "cache_hit_rate": 58.57,
  "by_country": {
    "DE": 342,
    "FR": 218,
    "LV": 156
  },
  "supported_countries": ["LV", "LT", "EE", "DE", "FR", "IE", "IT", "ES", "PT", "NL", "BE", "AT", "DK", "FI", "SE", "PL", "CZ", "SK", "HU", "SI", "HR", "RO", "BG", "MT", "LU", "CY"]
}

VIES vs VAT Validation API

This project offers two VAT validation endpoints. Choose the one that fits your use case:

Feature VIES API (/api/vies) VAT API (/api/vat)
Data Source EU VIES service (real-time) Local database (daily imports)
Country Coverage All 27 EU member states Format: 28 countries, Database: Latvia only
Validation Type Registration verification Format + local database check
Company Details Name + address (all countries) Full company data (Latvia only)
Availability Depends on EU service uptime Always available (local data)
Caching 24h (valid) / 1h (invalid) No caching needed (local queries)
Permission vies:read vat:read

Error Responses

The API returns standard HTTP status codes and JSON error responses:

Common Status Codes

Code Status Description
200 OK Validation completed successfully
401 Unauthorized Missing/invalid API token
403 Forbidden Insufficient permissions (requires vies:read)
422 Validation Error Invalid request parameters
503 Service Unavailable VIES service is temporarily down - retry later

Code Examples

PHP Example

<?php

$apiToken = 'YOUR_API_TOKEN';
$baseUrl = 'https://api.clients.lv/api/vies';

$data = ['vat_number' => 'DE123456789'];

$response = file_get_contents($baseUrl . '/validate', false, stream_context_create([
    'http' => [
        'method' => 'POST',
        'header' => [
            'Authorization: Bearer ' . $apiToken,
            'Content-Type: application/json',
            'Accept: application/json'
        ],
        'content' => json_encode($data)
    ]
]));

$result = json_decode($response, true);

if ($result['valid']) {
    echo "VAT Number: " . $result['vat_number'] . "\n";
    echo "Company: " . $result['company_name'] . "\n";
    echo "Address: " . $result['company_address'] . "\n";
} elseif (!$result['vies_available']) {
    echo "VIES service unavailable, try again later\n";
} else {
    echo "Invalid VAT number\n";
}

JavaScript Example

const apiToken = 'YOUR_API_TOKEN';
const baseUrl = 'https://api.clients.lv/api/vies';

async function validateVIES(vatNumber) {
    const response = await fetch(`${baseUrl}/validate`, {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${apiToken}`,
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
        body: JSON.stringify({ vat_number: vatNumber })
    });

    const result = await response.json();

    if (response.status === 503) {
        console.log('VIES service unavailable');
        return result;
    }

    if (result.valid) {
        console.log('Company:', result.company_name);
        console.log('Address:', result.company_address);
        console.log('Cached:', result.cached);
    } else {
        console.log('Invalid VAT:', result.error);
    }

    return result;
}

// Usage
validateVIES('DE123456789');
validateVIES('LV40203029397');

Integration Notes

Caching: Valid results are cached for 24 hours, invalid for 1 hour. The cached field indicates if the response came from cache.
VIES Availability: The EU VIES service has periodic maintenance windows (typically weeknights). When unavailable, the API returns HTTP 503. Implement retry logic in your application.
Format Validation: VAT numbers are format-validated before calling VIES. Invalid formats return immediately without making an external API call.
UK (GB) Numbers: GB VAT numbers cannot be validated via VIES since the UK left the EU. Use the UK's HMRC VAT API for GB numbers.
Company Data: Some EU member states do not disclose company name/address via VIES. In those cases, company_name and company_address will be null even for valid VAT numbers.