# Check VAT France API

## How to Check a French VAT Number via API

To check a French VAT number (numero de TVA intracommunautaire), 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. Unlike Germany or Spain, France returns both the company name and address from VIES, making it one of the most developer-friendly EU countries for VAT validation.

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

## French VAT Number Format

A French VAT number (numero de TVA intracommunautaire) consists of:

- **Country prefix:** `FR`
- **2-character validation key:** two digits, two letters, or one of each
- **9-digit SIREN number:** the company's official registration number

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

The validation key is calculated from the SIREN using modulo 97. This means the API can reject obviously invalid numbers before contacting VIES, saving your quota.

Examples:
- `FR40303265045` (Sodimas SA)
- `FR82542065479` (Danone SA)
- `FRXX999999999` (invalid key format)

The key can contain letters (A-Z except I and O) or digits. This catches developers off guard because most EU countries use digits only.

## Quick Examples

### curl

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

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

### 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('FR40303265045');

if (result.status === 'valid') {
  console.log('Company:', result.company_name);
  console.log('Address:', result.company_address);
  console.log('Country:', result.country_code);
} 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("FR40303265045")

print(f"Status: {result.status}")
print(f"Company: {result.company_name}")
print(f"Address: {result.company_address}")
print(f"Confidence: {result.meta.confidence}")
```

## Valid Response

```json
{
  "vat_number": "FR40303265045",
  "country_code": "FR",
  "status": "valid",
  "company_name": "SA SODIMAS",
  "company_address": "RUE DE LA PAIX 75002 PARIS",
  "request_id": "req_fr789",
  "meta": {
    "confidence": "high",
    "source": "vies_live",
    "cached": false,
    "response_time_ms": 203,
    "last_verified": "2026-04-12T09:00:00Z",
    "upstream_status": "ok"
  }
}
```

France returns both `company_name` and `company_address` from VIES. This is a significant advantage over Germany and Spain, which return `null` for both fields due to data protection restrictions.

## Invalid Response

```json
{
  "vat_number": "FR00000000000",
  "country_code": "FR",
  "status": "invalid",
  "company_name": null,
  "company_address": null,
  "request_id": "req_fr456",
  "meta": {
    "confidence": "high",
    "source": "vies_live",
    "cached": false,
    "response_time_ms": 195,
    "upstream_status": "ok"
  }
}
```

## Format Error Response (400)

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

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

## France vs Other EU Countries

| Country | Returns name? | Returns address? | Key format |
|---------|---------------|------------------|------------|
| France (FR) | Yes | Yes | 2 chars + 9 digits |
| Germany (DE) | No | No | 9 digits |
| Spain (ES) | No | No | Letter + 7 digits + letter/digit |
| Italy (IT) | Yes | Yes | 11 digits |
| Netherlands (NL) | Yes | Yes | 9 digits + B + 2 digits |

France is one of the best-behaved VIES responders. It has high uptime, returns full company data, and responds quickly compared to countries like Germany whose VIES backend is frequently overloaded.

## The Alphanumeric Key

The two-character key after `FR` trips up many developers. Unlike most EU countries where the VAT number is purely numeric after the prefix, France allows letters in positions 3 and 4.

Valid key patterns:
- Two digits: `FR40...` (most common)
- Two letters: `FRAB...` (excluding I and O)
- One digit + one letter: `FR4A...`
- One letter + one digit: `FRA4...`

If you pre-validate the format yourself before calling the API, your regex must account for this. The API handles it automatically, accepting any valid combination.

```javascript
// Correct regex for French VAT
const frVatRegex = /^FR[0-9A-HJ-NP-Z]{2}\d{9}$/;

// Wrong: digits only
const wrongRegex = /^FR\d{11}$/;
```

## Latency

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

France has one of the fastest and most reliable VIES backends. Typical response times are 150-250 ms for live lookups, consistently faster than Germany (250-400 ms) and Spain (200-350 ms).

## Common Pitfalls

**Rejecting letters in the key.** The two-character key after `FR` can contain letters A-H, J-N, P-Z. If your input validation rejects `FRAB123456789`, you are blocking valid VAT numbers.

**Confusing SIREN and SIRET.** French businesses have a 9-digit SIREN (company identifier) and a 14-digit SIRET (establishment identifier). The VAT number uses the SIREN, not the SIRET. If a customer provides a SIRET, take the first 9 digits.

**Case sensitivity.** Some systems send `fr40303265045`. The API normalizes case, but if you validate the prefix yourself, accept both `FR` and `fr`.

**Monaco companies.** Monaco uses French VAT numbers with the `FR` prefix. A valid `FR` VAT number might belong to a Monaco-registered entity. If you need to distinguish between France and Monaco for tax purposes, check the address field in the VIES response.

**DOM-TOM territories.** French overseas territories (Guadeloupe, Martinique, Reunion, etc.) are outside the EU VAT territory. Companies there may have SIREN numbers but no valid intra-community VAT number. The API will return `invalid` for these.

## Using Company Data from VIES

Since France returns company data, you can use it for:

1. **Auto-filling checkout forms** — pre-populate company name and address after VAT validation
2. **KYB verification** — cross-reference the VIES company name with what the customer entered
3. **Invoice generation** — use the official registered name and address on invoices

For richer company data (LEI, registration details), use the company lookup endpoint:

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

This queries GLEIF and returns additional data if the entity has a Legal Entity Identifier.

## Pricing

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

The free tier covers development and testing. Starter handles most B2B SaaS billing flows with French customers.

## 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/FR40303265045
```

## Related Pages

- [Check VAT Germany API](https://blog.eurovalidate.com/check-vat-germany-api)
- [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)
