# Check VAT Germany API

## How to Check a German VAT Number via API

To check a German VAT number (USt-IdNr), send a GET request to `https://api.eurovalidate.com/v1/vat/{number}` with your API key. The API validates the format locally, then queries VIES (the EU VAT Information Exchange System) and returns the result. There is one critical quirk: Germany never returns the company name from VIES due to data protection law. You will get a `valid` or `invalid` status, but `company_name` will always be `null`.

```bash
curl -H "X-API-Key: YOUR_API_KEY" \
  https://api.eurovalidate.com/v1/vat/DE136695976
```

## German VAT Number Format

A German VAT number (Umsatzsteuer-Identifikationsnummer, USt-IdNr) consists of:

- **Country prefix:** `DE`
- **9 digits:** any combination

Total length: **11 characters** including the prefix.

Examples:
- `DE136695976` (SAP SE)
- `DE811167738` (Adidas AG)
- `DE143484175` (Lufthansa)

The local format validation rejects anything that does not match `DE` + 9 digits before sending the request to VIES, saving your API quota.

## Quick Examples

### curl

```bash
# Valid German VAT
curl -H "X-API-Key: YOUR_KEY" \
  https://api.eurovalidate.com/v1/vat/DE136695976

# Wrong length (rejected locally with 400)
curl -H "X-API-Key: YOUR_KEY" \
  https://api.eurovalidate.com/v1/vat/DE12345
```

### Node.js

```bash
npm install @eurovalidate/sdk
```

```javascript
import { EuroValidate } from '@eurovalidate/sdk';

const ev = new EuroValidate(process.env.EUROVALIDATE_API_KEY);

const result = await ev.validateVat('DE136695976');

if (result.status === 'valid') {
  console.log('VAT is registered with VIES');
  console.log('Country:', result.country_code);
  // Note: company_name will be null for German VATs
} else {
  console.log('VAT is invalid or not registered');
}
```

### Python

```bash
pip install eurovalidate
```

```python
from eurovalidate import Client
import os

client = Client(api_key=os.environ["EUROVALIDATE_API_KEY"])
result = client.validate_vat("DE136695976")

print(f"Status: {result.status}")
print(f"Country: {result.country_code}")
print(f"Confidence: {result.meta.confidence}")
# result.company_name will be None for DE
```

## Valid Response

```json
{
  "vat_number": "DE136695976",
  "country_code": "DE",
  "status": "valid",
  "company_name": null,
  "company_address": null,
  "request_id": "req_xyz789",
  "meta": {
    "confidence": "high",
    "source": "vies_live",
    "cached": false,
    "response_time_ms": 312,
    "last_verified": "2026-04-10T09:00:00Z",
    "upstream_status": "ok"
  }
}
```

Notice that `company_name` and `company_address` are both `null` even though the status is `valid`. This is not a bug. Germany applies the Federal Data Protection Act (BDSG) and refuses to share trader name and address through VIES. You can confirm registration but you cannot get the company details.

## Invalid Response

```json
{
  "vat_number": "DE000000000",
  "country_code": "DE",
  "status": "invalid",
  "company_name": null,
  "company_address": null,
  "request_id": "req_abc123",
  "meta": {
    "confidence": "high",
    "source": "vies_live",
    "cached": false,
    "response_time_ms": 287,
    "upstream_status": "ok"
  }
}
```

## Format Error Response (400)

```json
{
  "type": "https://eurovalidate.dev/errors/http",
  "title": "VAT number for DE must be 9 characters (got 5)",
  "status": 400,
  "detail": "VAT number for DE must be 9 characters..."
}
```

The API returns 400 immediately for `DE12345` without contacting VIES. This protects your hourly quota from typos and bot input.

## The Germany Quirk: No Trader Data

German VAT validation behaves differently from most EU countries:

| Country | Returns name? | Returns address? |
|---------|---------------|------------------|
| Germany (DE) | No | No |
| Spain (ES) | No | No |
| France (FR) | Yes | Yes |
| Italy (IT) | Yes | Yes |
| Netherlands (NL) | Yes | Yes |

If you need the company name for a German VAT, you have to look it up separately:

1. Use the [GLEIF API](https://api.eurovalidate.com/docs) via `GET /v1/company/vat/{vat_number}` — works only if the entity has a Legal Entity Identifier
2. Cross-reference with the German Handelsregister (commercial register) — manual lookup
3. Ask the customer to provide the company name during signup

## Latency

| Scenario | Time |
|----------|------|
| Cached (Redis hit) | 1-5 ms |
| Live VIES call | 250-400 ms |
| Format error (no VIES call) | <10 ms |
| VIES timeout (rare) | 5-15 s |

Germany generates roughly 95% of all VIES errors because of its volume and the strict server-side rate limit (`MS_MAX_CONCURRENT_REQ`). EuroValidate handles this with a per-country circuit breaker: if Germany fails repeatedly, the breaker opens and serves cached results until VIES recovers.

## Common Pitfalls

**Treating null company_name as an error.** German VATs are fully valid even with `company_name: null`. Your code should check `status === 'valid'` independently of name presence.

**Case-sensitive prefix.** Some integrations send `de136695976`. The API normalizes case, but if you pre-validate format yourself, accept both `DE` and `de`.

**Wrong digit count.** German VATs have exactly 9 digits. `DE13669597` (8 digits) or `DE1366959760` (10 digits) both fail format validation.

**Confusing USt-IdNr with Steuernummer.** German businesses have two tax numbers: the local Steuernummer (`12/345/67890`) and the EU-wide USt-IdNr (`DE...`). VIES only accepts the EU-wide USt-IdNr.

**Trying to look up via /v1/company/vat for KYB.** Most German entities are not in the GLEIF database. Use VAT validation for tax compliance, but expect a 404 from the company lookup endpoint for typical SMEs.

## Pricing

| Tier | Price | Requests |
|------|-------|----------|
| Free | €0 | 100/hour |
| Starter | €19/mo | 5,000/hour |
| Growth | €49/mo | 25,000/hour |
| Scale | €149/mo | 100,000/hour |

Free tier is enough to test German VAT validation in development. Starter is suitable for most B2B SaaS billing flows.

## Try It Now

[Get a free API key](https://eurovalidate.com) and paste this into your terminal:

```bash
curl -H "X-API-Key: YOUR_KEY" \
  https://api.eurovalidate.com/v1/vat/DE136695976
```

## Related Pages

- [VAT validation REST API example](https://blog.eurovalidate.com/vat-validation-rest-api-example)
- [Validate EU VAT in Node.js](https://blog.eurovalidate.com/validate-eu-vat-nodejs)
- [Validate EU VAT in Python](https://blog.eurovalidate.com/validate-eu-vat-python)
- [Stripe VAT validation tutorial](https://blog.eurovalidate.com/validate-vat-stripe-subscriptions)
- [Why VIES is unreliable](https://blog.eurovalidate.com/why-vies-unreliable)
- [Full API documentation](https://api.eurovalidate.com/docs)
