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
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
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
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
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:
{
"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.
activeVAT number is valid and the business is registered
invalidVAT number format is wrong or not registered in VIES
service_unavailableVIES or the national system is temporarily down — retry later
Further reading
SaaS VAT Compliance: A Developer's Complete Guide for EU Markets
Selling a SaaS product to EU customers means navigating B2B vs B2C VAT rules, determining the place of supply, registeri…
B2B VAT Exemption in EU SaaS: What Your Billing System Must Do
Reverse charge sounds simple but the implementation details trip up most SaaS billing engineers. Here is what your syste…
Evaluating EU VAT APIs? Compare TaxID with:
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...