I’m building VAT Engine, an API for developers working on headless commerce, SaaS billing, custom checkouts, and other products that need EU VAT calculations.
The current API supports:
- EU VAT calculations
- Current and historical VAT rates
- Product tax classes
- VAT-inclusive and VAT-exclusive prices
- Source tagging for stores, storefronts, and sales channels
You can create a free account, generate an API key, and connect it to a real project or side project.
Example calculation
curl -X POST https://vat-engine.app/api/v1/vat/calculate \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"country": "DE",
"currency": "EUR",
"gross_amount_minor": 11900,
"price_includes_vat": true,
"tax_class_id": "standard",
"transaction_date": "2026-01-28"
}'
Example response:
{
"country": "DE",
"currency": "EUR",
"vat_rate_bps": 1900,
"gross_amount_minor": 11900,
"net_amount_minor": 10000,
"vat_amount_minor": 1900
}
Amounts are represented in minor currency units, while VAT rates use basis points to avoid floating-point ambiguity.
The API can be used in a headless checkout, SaaS billing flow, ecommerce integration, internal tool, or test project.
Free access is currently available here:
Feedback about the API contract, documentation, onboarding, or missing developer functionality is welcome.
Top comments (2)
Cool project. One thing I would think about early is how the response model handles stacked taxes. Your contract returns a single rate, which is fine for EU VAT, but a lot of tax regimes apply two components at once. Canada is the classic example: BC charges 5 percent GST plus 7 percent PST on the same sale, and Quebec charges 5 percent GST plus 9.975 percent QST where the QST is calculated on the price before GST, not on the GST inclusive amount. A flat single rate field makes that math awkward to represent. If you ever want to go beyond Europe, a components array with per component rates and bases would save you from a breaking change later. The source tagging and minor units approach look solid though.
Thanks — that’s a really good point. The current public contract is intentionally EU VAT–focused, so a single vat_rate_bps works for the scope I’m targeting today.
I agree that trying to stretch that same field into jurisdictions with stacked or dependent taxes would get awkward very quickly. If VAT Engine expands beyond EU VAT, I’d rather model that explicitly as tax components with their own rate, base, and calculation order than overload the existing single-rate field.
So I’m keeping the current contract narrow for now, but your point about avoiding a breaking change later is definitely worth accounting for in the internal model. And thanks for the note on source tagging/minor units too.