Home / VAT API / Integrations / Go

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.

VIES-backedSub-100ms cachedFree plan available27 EU countries

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:

200 OK — valid numbervalid
{
  "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..."
}
active

VAT number is valid and the business is registered

invalid

VAT number format is wrong or not registered in VIES

service_unavailable

VIES or the national authority is temporarily down — retry later, do not silently zero-rate

Implementation steps

  1. 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. 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. 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. 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.

Other integrations

Stripe

Validate EU VAT numbers before applying Stripe reverse-charge

Shopify

EU VAT validation for Shopify B2B storefronts

Node.js

EU VAT validation in Node.js with a single HTTP call

Python

Validate EU VAT numbers from Python with requests or httpx