Home / VAT API / Integrations / .NET / C#
.NET / C# EU VAT Validation API
Validate EU VAT numbers in .NET and C# with the TaxID API using HttpClient and IHttpClientFactory. Add it to an ASP.NET Core service or a minimal-API endpoint so VAT numbers are verified against VIES before your application applies reverse-charge treatment or writes a customer to the database.
Quick start
CURL
curl -H "Authorization: Bearer YOUR_API_KEY" \ https://www.taxid.dev/api/v1/validate/DE/DE123456789
Code example
Full integration example including error handling for service_unavailable responses from VIES.
C# / .NET
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
public record VATResult(
[property: JsonPropertyName("valid")] bool Valid,
[property: JsonPropertyName("status")] string Status,
[property: JsonPropertyName("company_name")] string? CompanyName,
[property: JsonPropertyName("company_address")] string? CompanyAddress
);
// In your service — register HttpClient via IHttpClientFactory in prod
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer",
Environment.GetEnvironmentVariable("TAXID_API_KEY"));
var url = $"https://www.taxid.dev/api/v1/validate/DE/DE123456789";
var json = await http.GetStringAsync(url);
var result = JsonSerializer.Deserialize<VATResult>(json)!;
if (result.Valid)
Console.WriteLine($"Valid EU business: {result.CompanyName}");
else if (result.Status == "service_unavailable")
Console.WriteLine("VIES unavailable — retry later");
else
Console.WriteLine("Invalid VAT number");cURL
curl "https://www.taxid.dev/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:
{
"valid": true,
"status": "active",
"country_code": "DE",
"vat_number": "DE123456789",
"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..."
}activeVAT number is valid and the business is registered
invalidVAT number format is wrong or not registered in VIES
service_unavailableVIES or the national authority is temporarily down — retry later, do not silently zero-rate
Implementation steps
- 1
Get a free TaxID API key
Sign up at taxid.dev/signup for a free key with 100 validations/month. Store it in user-secrets during development (dotnet user-secrets set) and in your host's configuration or Key Vault in production, then bind it through IConfiguration — never in appsettings.json committed to source control.
- 2
Register a typed HttpClient
In Program.cs, call builder.Services.AddHttpClient<VatValidationClient>() so IHttpClientFactory manages the handler lifetime and connection pooling. Set the Authorization bearer header and a 10-second timeout on the typed client. This avoids the socket-exhaustion problems of newing up HttpClient per request.
- 3
Deserialize the response
Define a VatResult record with [JsonPropertyName] attributes for valid, status, company_name, and company_address, then read the endpoint with GetFromJsonAsync<VatResult>. Check that Status == "active" before applying any tax exemption; branch on "service_unavailable" separately from "invalid".
- 4
Validate at the API boundary
Call the client from a minimal-API endpoint or an MVC controller action during checkout or onboarding, returning a 400 ProblemDetails when the number is invalid. On success, persist company_name, company_address, and a ValidatedAt timestamp on your EF Core entity for the audit trail.
- 5
Re-validate with a hosted service
Add a BackgroundService (IHostedService) or a Hangfire recurring job that re-validates customers flagged for reverse-charge monthly. Registrations can lapse between billing cycles. On a 'service_unavailable' response, skip and retry later instead of clearing the exemption flag.
Frequently asked questions
Why should I use IHttpClientFactory for VAT validation in .NET?
Instantiating HttpClient per request can exhaust available sockets under load, while a single static instance won't honor DNS changes. IHttpClientFactory solves both by pooling and rotating handlers. Register a typed client with AddHttpClient<VatValidationClient>() and inject it wherever you validate.
How do I deserialize the TaxID response in C#?
Create a record with System.Text.Json [JsonPropertyName] attributes mapping to valid, status, company_name, and company_address, then call GetFromJsonAsync<VatResult>() on the HttpClient. The snake_case JSON maps cleanly to your PascalCase properties via the attributes.
Where should I store the API key in an ASP.NET Core app?
Use the Secret Manager (dotnet user-secrets) in development and Azure Key Vault, AWS Secrets Manager, or environment variables in production, bound through IConfiguration. Keep the key out of appsettings.json and any file tracked in git.
How do I distinguish an invalid number from a VIES outage?
Branch on the status field: 'invalid' means the number is genuinely not registered and you should charge local VAT, while 'service_unavailable' means the registry is temporarily down. Never treat 'service_unavailable' as invalid — retry it from a background service instead.
Country-specific API docs:
In-depth integration guide:
EU VAT validation in .NET / C#
Validate EU VAT numbers in .NET 6+ and C# using HttpClient and System.Text.Json. Includes async/await pattern, strongly-typed response record, and IHttpClientFactory-ready setup.
Start validating EU VAT numbers in .NET / C#
Free plan — 100 validations/month. No credit card required.