Home / Use cases / Custom

Custom

EU OSS VAT validation for digital services

Validate customer registration status for EU One Stop Shop (OSS) digital services compliance. Determine whether B2B reverse charge applies or you must collect and remit local VAT.

Under the EU VAT rules for digital services (effective 2015, consolidated in the 2021 OSS reform), a supplier of electronically supplied services must charge VAT at the rate applicable in the customer's country of residence when selling to EU consumers. However, when the customer is a VAT-registered business in another EU member state, the supply falls under the reverse-charge mechanism (EU VAT Directive Article 196) and the supplier charges zero VAT. The entire tax obligation classification — OSS B2C at local rate, or reverse-charge B2B at zero — therefore hinges on whether the customer holds a valid VAT number.

The decision tree at checkout is: does the customer provide a VAT number? If yes, call GET /api/v1/validate/:country/:vat. If status: 'active', classify as B2B reverse-charge, charge zero VAT, and record for the OSS return as a non-reportable B2B supply. If status: 'invalid' or no VAT number provided, classify as B2C, determine the customer's country from billing address (two-factor evidence is best practice: IP geolocation + billing country), look up the local VAT rate, and record the transaction for the OSS quarterly return.

OSS returns are filed quarterly and must separately report each member state's B2C revenue at that state's VAT rate. Maintaining a clean classification at the transaction level — storing each order's vat_treatment ('reverse_charge' or 'oss_b2c'), the customer's member state, and the applied rate — makes the quarterly OSS filing a straightforward aggregation rather than a retroactive classification exercise.

Implementation steps

  1. 1

    Determine customer location

    Collect two non-contradictory pieces of evidence for the customer's EU member state: their billing address country and their IP geolocation country. EU VAT rules for digital services require two-factor evidence to determine the place of supply; a single data point (e.g. billing country alone) can be challenged by tax authorities. If both factors agree, use that country as the place of supply; if they conflict, apply the customer's declared billing address with a note for audit purposes.

  2. 2

    Validate VAT number for B2B classification

    Call GET /api/v1/validate/:country/:vat when the customer provides a VAT number at checkout. A response of status: 'active' classifies the sale as B2B reverse-charge: set vat_treatment: 'reverse_charge' and zero_rate: true on the order. A response of status: 'invalid' reverts the customer to B2C classification; do not block the purchase, but do flag the invalid number so your support team can follow up. For status: 'service_unavailable', hold the B2B classification pending re-validation and apply standard VAT conservatively.

  3. 3

    Apply reverse charge or local VAT rate

    For B2B reverse-charge orders, issue the invoice with zero VAT and include the annotation 'VAT reverse charged — Article 196 EU VAT Directive' and the buyer's validated VAT number. For B2C orders, apply the VAT rate for the customer's member state: maintain a rate table keyed by ISO country code (e.g. DE: 19%, FR: 20%, IT: 22%, ES: 21%) or use a tax provider such as Stripe Tax or Avalara that handles rate lookups automatically.

  4. 4

    Record for OSS quarterly returns

    Store each transaction with: vat_treatment ('reverse_charge' | 'oss_b2c'), member_state (ISO code), vat_rate_applied, vat_amount, and net_amount. At quarter-end, aggregate oss_b2c rows by member_state to produce the per-country revenue and VAT amounts for the OSS return filed in your EU registration country. Reverse-charge transactions are excluded from OSS reporting — they are reported only by the buyer on their local VAT return.

Code example

Node.js

const res = await fetch(
  'http://localhost:3000/api/v1/validate/DE/DE123456789',
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const { valid, status, company_name, company_address } = await res.json();

if (valid) {
  console.log(`Valid EU business: ${company_name}`);
} else if (status === 'service_unavailable') {
  // VIES is temporarily down — retry or allow with manual check
  console.log('VIES unavailable — check back in a few minutes');
} else {
  console.log('Invalid VAT number — charge local tax rate');
}

Python

import requests

res = requests.get(
    "http://localhost:3000/api/v1/validate/DE/DE123456789",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = res.json()

if data["valid"]:
    print(f"Valid: {data['company_name']}")
elif data["status"] == "service_unavailable":
    print("VIES temporarily unavailable")
else:
    print("Invalid VAT number")

API response

The TaxID API returns a consistent JSON response for every validation request:

200 OK (active)valid
{
  "valid": true,
  "status": "active",
  "country_code": "DE",
  "vat_number": "123456789",
  "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..."
}

Error handling

The API uses a consistent Stripe-style error format. Always handle service_unavailable separately — VIES has occasional downtime and you should not reject valid customers during outages.

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 system is temporarily down — retry later

Further reading

Evaluating EU VAT APIs? Compare TaxID with:

Ready to implement?

Get your free API key and start validating EU VAT numbers today.

Get free API key

Related use cases

EU VAT compliance for SaaS billing

Handle EU VAT for SaaS subscriptions. Validate customer VAT numbers at signup, determine B2B vs B2C ...

DAC7 marketplace seller VAT verification

Verify seller VAT numbers during marketplace onboarding for DAC7 compliance. EU platforms must colle...

Bulk VAT number validation via CSV import

Validate hundreds of EU VAT numbers in batch using parallel API requests. Ideal for CRM data cleansi...