vat.toolsDocumentation
Open workspace

The evidence model

Claims, sources, observation time, freshness, and what an outcome does not say.

A VAT.tools result is not a fact about the world. It is a claim: one scoped assertion about a legal entity, an establishment, a VAT registration, or a relationship, together with typed evidence that supports it. This page explains the vocabulary the API encodes.

What a claim is

A response can carry several claims at once — that an entity is active, that a particular VAT identifier is valid, that an entity and a registration are related. Each claim has its own outcome and its own references into the evidence list. Two claims can disagree without the response being broken; the product surfaces that as conflicting rather than picking a winner.

Outcome vocabulary

Outcomes are typed, and only some of them are conclusions. The distinction is the reason this API exists in this shape.

FieldTypeDescription
validauthorityThe authority reported the registration as valid at the recorded time.
invalidauthorityThe authority explicitly reported the identifier as not valid. Only this outcome may block under a configured policy.
source_unavailableno answerThe authority or path could not answer. Retry later or route to review; never render as invalid.
unsupportedno coverageThe operation or jurisdiction is outside supported coverage for this source. Show “not available here”.
not_foundscoped absenceNo result in the queried source population. It is scoped to that source, not a statement about the entity.
conflictingdisagreementEligible evidence sources materially disagree. Each observation stays visible until a claim policy resolves it.

The evidence record

Every claim points at evidence. The evidence record is the provenance an integration must preserve when it stores or displays a result.

FieldTypeDescription
sourcerequiredobjectThe authority or registry that produced the observation, with an optional URL.
capabilityrequiredstringThe capability the source answered for, such as vat_validation or company_verification.
authorityScopestring | nullThe jurisdiction or scope the source's answer covers.
observedAtrequireddatetimeWhen the source recorded the fact. This time never changes when the same evidence is served again.
retrievedAt / servedAtrequireddatetimeWhen VAT.tools retrieved the evidence and when it delivered it. Delivery time is not observation time.
deliveryFormrequiredenumlive_source_call, official_snapshot, cached_observation, coalesced_observation, or sandbox_fixture.
completionobjectWhether the source answered completely, and the boundary it answered within.
Every successful response is one versioned envelope. These six parts are always present, and always attributed.
Operation

Who ran what, in which environment, and whether this response is a replay of an earlier one.

"operation": {
  "id": "0f6c2a90-1b3e-4c5d-9a7f-2e4b6c8d0a12",
  "kind": "vat_validation",
  "status": "completed",
  "environment": "sandbox",
  "createdAt": "2026-09-14T09:12:04.118Z",
  "completedAt": "2026-09-14T09:12:04.481Z",
  "replayed": false
}
Result

The operation's own answer. Only an authority outcome says valid or invalid; unsupported and source_unavailable never do.

"result": {
  "kind": "vat_validation",
  "outcome": "valid",
  "vatRegistration": { "countryCode": "DE", "vatNumber": "123456789" },
  "legalName": null,
  "checkedAt": "2026-09-14T09:12:04.470Z",
  "cached": false,
  "evidenceRefs": ["ev-1"]
}
Claims & relationships

Scoped assertions and the links between entities and registrations. Each one keeps the evidence that supports it.

"claims": [],
"relationships": [
  {
    "type": "vat_registration_of",
    "outcome": "confirmed",
    "vatRegistration": { "countryCode": "DE", "vatNumber": "123456789" },
    "evidenceRefs": ["ev-1"]
  }
],
"conflicts": [], "issues": []
Evidence

The source leaves its fingerprint: who answered, when it was observed, and how it was delivered.

"evidence": [
  {
    "id": "ev-1",
    "source": { "name": "Bundeszentralamt für Steuern", "url": null },
    "capability": "vat_validation",
    "environment": "sandbox",
    "authorityScope": "EU",
    "observedAt": "2026-09-14T09:12:04.470Z",
    "retrievedAt": "2026-09-14T09:12:04.481Z",
    "servedAt": "2026-09-14T09:12:04.481Z",
    "deliveryForm": "sandbox_fixture",
    "completion": { "state": "complete", "boundary": "authority" }
  }
]
Freshness

How long this answer stays current, plus the source's own cadence — which a faster delivery cannot change.

"freshness": {
  "effectiveMaxAgeSeconds": 86400,
  "satisfied": true,
  "sourceCadenceSeconds": 21600,
  "limitation": "Authority cadence is unchanged by this delivery."
}
Usage

What the call consumed and how it settled. A replay settles at zero.

"usage": {
  "meter": "vat_validation",
  "unitsCharged": 1,
  "settlementReason": "completed"
}

Freshness and cached evidence

Freshness is a property of the evidence, not of when you asked. A response reports the source's own cadence and the window within which the answer is considered current. Serving a stored result again produces cached evidence: same observation time, a new delivery time, and an explicit label.

Do not refresh observedAt

A later retrieval of an earlier observation is not a new observation. If you display a cached result, show its original observation time and say that it is cached.

When the window closes

Past the effective window, or when the caller requires fresher evidence, the correct behaviour is to re-check. Live-only operations such as company resolution always re-check; a cache can never answer a resolution.

Association is not validity

Reverse VAT discovery returns two different things that are easy to conflate: a VAT association — a sourced link between a legal entity and a registration — and, separately, the validity of that registration from an authority. An entity can be associated with a registration whose current status you have not checked, and a valid identifier does not by itself prove any company claim.

See the discovery operation →