VAT Engine journal
How VAT Calculation Provenance Makes Results Explainable
A VAT result is easier to trust when you can explain where the rate came from, which calculation contract ran, and what evidence was preserved.
- Engineering
A VAT calculation can be numerically correct and still be difficult to trust.
Imagine an API returns:
{
"net_amount_minor": 10000,
"vat_amount_minor": 1900,
"gross_amount_minor": 11900,
"vat_rate_bps": 1900
}
The arithmetic looks straightforward.
But if someone reviews that result six months later, they may ask:
- Where did the 19% rate come from?
- Which rate dataset was used?
- Which mapping participated in the decision?
- Which version of the calculator produced the amounts?
- What evidence was actually captured?
- Can the original result be reproduced exactly?
- Has the underlying rate data changed since then?
The final number alone cannot answer those questions.
That is what calculation provenance is for.
Provenance connects a financial result to the data, versions, mappings, and calculation contract that produced it.
For a VAT API, that can make the difference between:
VAT = €19.00
and:
VAT = €19.00
because this rate evidence, mapping context, date, and calculation contract produced it
The second result is much easier to explain.
A result and its provenance are different things
The result tells you what was calculated.
Provenance helps explain how the system arrived there.
A VAT result might contain:
{
"vat_rate_bps": 1900,
"net_amount_minor": 10000,
"vat_amount_minor": 1900,
"gross_amount_minor": 11900
}
Its provenance can describe things such as:
rate source
rate data version
mapping version
effective date
calculation version
evidence status
source references
replay status
These serve different purposes.
The calculation output is useful for checkout, invoices, reporting, and reconciliation.
The provenance becomes useful when someone needs to understand or review the result later.
Why the percentage alone is not enough
Consider two calculations that both use:
19%
They may look identical numerically.
But they could have been selected through completely different evidence paths.
For example:
Calculation A:
country = DE
tax class = standard
reviewed rate evidence = A
Calculation B:
country = DE
tax class = standard
legacy recorded window = B
Both might produce:
1900 basis points
That does not mean they have the same provenance.
A matching percentage does not prove:
- the same source was used
- the same historical applicability was established
- the same mapping was used
- or the same evidence quality existed
Numeric equality is not provenance.
Start with rate provenance
VAT Engine separates the numeric VAT rate from the evidence describing where that rate came from.
A response can include a structure such as:
{
"rate_provenance": {
"schema_version": "rate-evidence/v1",
"evidence_status": "legacy_unverifiable",
"source": "legacy_recorded_window",
"effective_at": "2026-01-28T00:00:00Z",
"source_evidence": []
}
}
The important part is not the exact JSON shape.
It is that the API does not pretend:
rate = 19%
is the complete explanation.
Instead, the result can carry information about the evidence state behind that rate.
Evidence status should be explicit
A common design mistake is to reduce evidence to:
{
"verified": true
}
That usually hides too much.
Historical and financial data often has more than two meaningful states.
For rate evidence, VAT Engine distinguishes states such as:
verified
legacy_unverifiable
unavailable
These communicate different things.
verified
The required reviewed rate evidence is available for that recorded path.
legacy_unverifiable
The historical record exists, but the evidence needed to prove it to the current standard was not captured.
unavailable
The required evidence cannot currently be established.
This is more informative than silently converting uncertainty into certainty.
Legacy records should stay legacy
Suppose an old VAT calculation used a recorded rate of:
19%
Later, a reviewed source also contains:
19%
It can be tempting to mark the old record as verified.
But the old record may not contain:
- the original reviewed source version,
- source-supported applicability evidence,
- the original mapping digest,
- or the source references needed by the newer evidence model.
So the safer rule is:
Do not retroactively upgrade provenance merely because the numbers match.
VAT Engine keeps that distinction explicit.
Older records can remain:
legacy_unverifiable
instead of being assigned stronger provenance by inference.
That preserves what the system actually knows.
Historical rate windows need careful interpretation
This matters especially for historical VAT data.
A recorded lookup window may describe:
when the system observed or applied a rate
while legal applicability asks:
when the rate was actually applicable according to the authoritative source
Those are not automatically the same thing.
Older imported or live-recorded windows can reflect observation or application time.
Where approved source-supported coverage exists, the evidence can be stronger.
But a legacy recorded window should not suddenly be described as a legally verified applicability interval.
That distinction is part of provenance.
I covered this temporal boundary in more detail here:
Current VAT Rate vs Transaction-Date VAT Rate: Why the Difference Matters (opens in a new tab)
Mapping provenance matters too
A VAT rate is usually not selected from country alone.
The system may need to resolve something like:
product or classification context
→ mapping
→ tax treatment
→ rate
Mappings can change over time.
If a mapping changes in July, the current mapping does not necessarily explain why a January calculation produced its result.
That is why a calculation record can benefit from preserving mapping identity.
VAT Engine can retain fields such as:
mapping_version
mapping digest
alongside rate evidence.
This lets a later review distinguish:
the mapping used then
from:
the mapping configured now
Calculation provenance is separate from rate provenance
Even if the selected rate is fully understood, the arithmetic still has its own provenance.
A financial calculation can depend on:
- rounding rules
- inclusive vs exclusive pricing
- currency scale
- validation behavior
- calculator version
VAT Engine therefore exposes calculation provenance separately.
For example:
{
"calculation_provenance": {
"schema_version": "calculation-evidence/v1",
"calculation_version": "vat-calculator-half-up/v1",
"execution_digest": "...",
"algorithm_manifest_version": "vat-algorithm-manifest/v1",
"algorithm_manifest_digest": "...",
"ownership": "tenant_owned",
"evidence_status": "captured",
"replay_status": "ineligible"
}
}
This answers a different question:
Which registered calculation contract produced these amounts?
That remains useful even if the VAT rate itself has not changed.
Why calculator versions matter
Financial software evolves.
Imagine that a later calculator version changes:
rounding behavior
currency-scale handling
validation rules
If an old transaction is reviewed after that change, running today's code may not be enough to explain yesterday's result.
Without calculation provenance, the investigation becomes:
Why does the API behave differently now?
With provenance, the question becomes:
Which calculation contract produced the original result?
That is much more precise.
An execution digest is not a source-code hash
Technical provenance should also be described carefully.
VAT Engine exposes an:
execution_digest
That is not presented as:
a hash of the compiled binary
or:
cryptographic proof of every runtime instruction
It identifies the registered calculation-version contract.
VAT Engine can also retain an algorithm manifest version and digest that bind the defined arithmetic, validation, currency-scale, rounding, and frozen-fixture contract.
That gives the result a stable technical identity without claiming more than the evidence actually proves.
Provenance should survive software updates
Your software will change.
Your rate imports will change.
Your mappings may change.
Your validation rules may change.
A historical calculation should not require today's mutable configuration to explain yesterday's result.
Instead, the record should preserve enough information to say:
this result came from this request
using this rate evidence
using this mapping context
using this calculation contract
That makes historical behavior less dependent on current state.
Provenance improves debugging
Imagine a customer reports:
Your API charged 19% VAT, but I expected 7%.
Without provenance, the investigation might require reconstructing:
- which rate data was active
- which tax class or mapping was selected
- which transaction date was used
- which calculator behavior was running
With provenance, much of that context can already be attached to the calculation record.
A review becomes more structured:
1. Retrieve the calculation.
2. Inspect the transaction date.
3. Inspect the selected tax context.
4. Inspect the rate evidence.
5. Inspect the mapping version.
6. Inspect the calculator version.
7. Compare the recorded assumptions with the expected business facts.
This does not automatically prove that the tax treatment was legally correct.
It does make the technical decision much easier to explain.
Provenance improves reconciliation too
Reconciliation often means comparing two systems.
For example:
VAT Engine
vs
Shopify
VAT Engine
vs
a billing platform
VAT Engine
vs
an accounting export
If both systems show:
VAT = €19.00
there may be nothing to investigate.
But if one says:
€19.00
and the other says:
€7.00
the useful question is not just:
Which number is correct?
You also need to know:
Which assumptions produced each number?
That may include:
- jurisdiction
- product classification
- transaction date
- rate source
- amount basis
- rounding behavior
Provenance turns reconciliation from a number comparison into a decision comparison.
Source references make evidence inspectable
A useful provenance model can include bounded references to the evidence behind a decision.
For reviewed rate paths, this can include public-safe references associated with:
rate versions
source snapshots
rate rows
mapping evidence
The public response does not need to expose every internal database object.
It needs enough stable, safe references to explain what the system relied on.
This keeps the API useful without leaking internal implementation details.
Provenance is not the same as logging
Logging and provenance overlap, but they are not interchangeable.
A log might say:
2026-01-28 10:03:12 calculated VAT for DE
That is operational telemetry.
Provenance belongs to the calculation record itself.
It answers questions such as:
Which rate source?
Which version?
Which mapping?
Which calculator?
Which evidence status?
Logs can be rotated.
Trace IDs can disappear.
Infrastructure can change.
The stored calculation should still retain the information needed to explain its own result.
Provenance is not a committed sale either
Another boundary matters.
A calculation with useful provenance is still a calculation.
It does not automatically mean:
a sale happened
or:
this record is a committed accounting event
VAT Engine's Transactions API exposes VAT calculation history and evidence.
Calling:
POST /v1/vat/calculate
records calculation history, but does not by itself add a sale to:
- OSS threshold monitoring,
- Filing Prep,
- OSS/IOSS reporting.
Those workflows use committed supply data.
Calculation provenance explains the API calculation.
It does not manufacture a business event.
Provenance and replay are related, but not identical
Another useful distinction is between:
evidence captured
and:
exactly replayable
A calculation may retain useful evidence without retaining everything required for exact replay.
VAT Engine exposes that boundary through:
replay_status
Possible states include:
not_supported
ineligible
available
Only calculations reporting:
replay_status: available
can use the exact replay endpoint.
That prevents the API from claiming reproducibility where the required sealed evidence does not exist.
Exact replay makes provenance testable
For eligible calculations:
POST /v1/transactions/{id}/replay
uses the recorded:
original canonical request
+ sealed historical rate evidence
+ registered calculator version
A successful replay returns:
exact_match: true
with the reproduced amounts.
This makes provenance stronger than descriptive metadata alone.
The system can test whether the recorded evidence reproduces the stored result.
But replay still has strict boundaries.
The caller cannot choose:
another rate-data version
another calculator version
because that would describe a different calculation, not a replay of the original one.
A useful provenance record answers several layers of "why"
When someone asks:
Why is the VAT €19?
there are several possible meanings.
Arithmetic
Why is €19 the mathematical VAT amount?
Answer:
because €100 net at 19% produces €19 VAT
Rate selection
Why was 19% selected?
Answer:
because this recorded rate evidence was selected for this context and date
Mapping
Why did this product or classification use that treatment?
Answer:
because this recorded mapping context participated in the decision
Reproducibility
Can we reproduce the original result?
Answer:
only when the required sealed evidence exists and replay_status is available
A single vat_rate field cannot answer all of those questions.
Provenance gives each one a place in the model.
What I would preserve in a provenance-aware VAT API
At minimum, I would separate the result from the evidence explaining it.
A useful structure might preserve:
Calculation identity
Input context:
- country / jurisdiction
- currency
- amount basis
- tax classification
- transaction date
Result:
- net amount
- VAT amount
- gross amount
- selected VAT rate
Rate provenance:
- evidence status
- rate source
- rate data version
- effective date
- rate-row identity
- source references where available
Mapping provenance:
- mapping version
- mapping digest or stable identity
Calculation provenance:
- calculation version
- execution identity
- algorithm manifest identity
- calculation evidence state
Reproducibility:
- replay status
Not every financial API needs exactly these field names.
The architectural point is the separation.
What provenance should not do
Provenance is useful because it describes what the system actually knows.
It should not silently invent stronger claims.
Avoid patterns such as:
Upgrading old history because the number matches
old rate = 19%
reviewed rate = 19%
therefore old history is verified
That does not follow.
Treating a recorded window as automatic legal applicability
Recorded/imported windows can reflect system history rather than authoritative legal dates.
Calling evidence capture exact replay
Evidence can be useful without being complete enough for replay.
Treating calculation history as a committed sale
A calculator call does not prove that a business transaction occurred.
Hiding uncertainty
legacy_unverifiable is more informative than pretending old evidence is equivalent to newly reviewed evidence.
Explainability is mostly about preserving context
A financial API does not become explainable because it adds a field called:
reason
Explainability comes from preserving the actual chain of context behind the result.
For VAT, that can look like:
business input
→ classification or mapping
→ rate evidence
→ calculation contract
→ result
If those links survive, the result remains understandable even after the software changes.
If they disappear, a historical VAT amount becomes just another unexplained number in a database.
The goal is not to store everything
There is a balance.
A provenance-aware API should not dump:
every SQL row
every internal log
every deployment detail
every implementation object
into every response.
The goal is to preserve the identities and evidence boundaries that matter.
That usually means:
- stable versions
- digests or identifiers
- evidence states
- bounded public references
- and enough context to reproduce or review the decision
Good provenance is not maximum data.
It is the right data.
A financial result should be able to explain itself
The most useful way to think about provenance is this:
A stored calculation should carry enough context that a future version of your system can still explain why the result exists.
For VAT, that means going beyond:
19%
and preserving:
where the rate came from
which mapping participated
which calculation contract ran
what evidence was available
whether the result can be replayed
That does not turn an API into a tax authority.
It does make the API's own decisions easier to inspect, debug, reconcile, and reproduce.
For financial software, that is a meaningful improvement over returning the right number and forgetting how you got there.
You can inspect the current VAT Engine calculation contract here:
Calculate VAT API (opens in a new tab)
The stored evidence and replay model:
Transactions API (opens in a new tab)
And the historical-rate evidence boundary:
VAT Rates API (opens in a new tab)
VAT Engine is currently in active alpha development. Evidence strength varies by record and source coverage; older records can remain legacy_unverifiable, and provenance does not by itself establish legal or tax correctness. VAT Engine does not provide tax or legal advice.
- VAT API
- EU VAT
- Calculation Provenance
- API Design
- Financial Software
- Auditability