Home / VAT API / Integrations / Go
Go EU VAT Validation API
Validate EU VAT numbers from Go backends using only the standard library. Returns VIES registration status, company name, and address in a single REST call — no SOAP, no XML, no external packages required.
Quick start
CURL
curl -H "Authorization: Bearer YOUR_API_KEY" \ http://localhost:3000/api/v1/validate/DE/DE123456789
Code example
Full integration example including error handling for service_unavailable responses from VIES.
Go
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func validateVAT(country, vatNumber string) (map[string]any, error) {
url := fmt.Sprintf("http://localhost:3000/api/v1/validate/%s/%s", country, vatNumber)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("TAXID_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result map[string]any
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}
func main() {
result, _ := validateVAT("DE", "DE123456789")
if result["valid"] == true {
fmt.Println("Valid EU business:", result["company_name"])
} else if result["status"] == "service_unavailable" {
fmt.Println("VIES unavailable — retry later")
} else {
fmt.Println("Invalid VAT number")
}
}cURL
curl "http://localhost:3000/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. Store your API key as an environment variable (export TAXID_API_KEY=your_key) and read it with os.Getenv(). Never hardcode credentials in source files.
- 2
Make a GET request with net/http
Create an http.Request with http.NewRequest("GET", url, nil), set the Authorization header, and call http.DefaultClient.Do(req). This uses only the Go standard library — no external packages or go get required.
- 3
Decode the JSON response
Use json.NewDecoder(resp.Body).Decode(&result) to parse the response into a map[string]any or a typed struct. Check result["valid"] == true for an active EU business, and result["status"] for the detailed outcome ('active', 'invalid', 'not_found', 'service_unavailable').
- 4
Handle service_unavailable and implement retries
VIES has occasional downtime. When status is 'service_unavailable', return a distinct error type from your validate function so callers can handle it differently from an invalid VAT number. Implement exponential backoff with a maximum of 3 retries for transient errors.
Frequently asked questions
Do I need any Go packages to call the TaxID API?
No. The TaxID API is a plain REST/JSON endpoint — Go's standard library (net/http + encoding/json) is all you need. This avoids adding external dependencies to your go.mod for a simple HTTP call.
How do I create a typed struct for the TaxID API response in Go?
Define a struct with json tags matching the response fields: type VATResult struct { Valid bool `json:"valid"`; Status string `json:"status"`; CompanyName *string `json:"company_name"`; CompanyAddress *string `json:"company_address"` }. Use a pointer for nullable fields so you can distinguish null from empty string.
How do I validate multiple EU VAT numbers in Go?
Use the batch endpoint: POST /api/v1/validate with Content-Type: application/json and a body like {"numbers": [{"country": "DE", "vat": "DE123456789"}]}. Alternatively, fan out multiple concurrent GET requests using goroutines and collect results via a channel — the single-validation endpoint is designed for concurrent use.
Can I use the TaxID API inside a gRPC service?
Yes. Call the TaxID REST API from your gRPC service handler using net/http. Since gRPC handlers run in goroutines, use a shared http.Client with connection pooling (set MaxIdleConnsPerHost) to avoid opening a new TCP connection per validation request.
Country-specific API docs:
Start validating EU VAT numbers in Go
Free plan — 100 validations/month. No credit card required.