Skip to main content

Caching

Avatcado caches validation results so repeat lookups return faster and your integration stays resilient even when upstream services (VIES, HMRC, BFS, Bronnoysund, or ABR) are down.

How it works

  • TTL: Validation results are cached for 25 days
  • Cache key: The combination of the VAT number and the requester VAT number (if provided)
  • Storage: Cached in the database alongside fresh results
  • Consultation numbers: a request that carries requester_vat_number skips the cache by default, so the consultation number always comes from a fresh check. Pass cache=true to opt back in (see Consultation numbers)

Detecting cached responses

When a result comes from cache, several fields in the meta object reflect it:

Usage counting

Cached responses still count toward your monthly quota. This is because caching is a performance optimization, not a billing bypass. Check your remaining quota via the X-RateLimit-Remaining header on each response.

Stale cache fallback

When an upstream service (VIES, HMRC, BFS, Bronnoysund, or ABR) is down and no fresh cache exists (within the 25-day TTL), Avatcado falls back to the most recent cached result for that VAT number, regardless of age. The response includes meta.stale: true so you know the data may be outdated:
Stale results still count toward your monthly quota because you received data. If no cached result exists at all for the requested VAT number, the API returns a 503 error and that request is automatically refunded. See Non-billable failures for details.

Source status

Every validation response includes meta.source_status (how the result was obtained) and meta.source (which registry produced it): The national register step runs on Pro and Business plans. On the Free plan a member state outage goes straight to the cache: the most recent stored result is served with source_status: "unavailable", and when nothing is stored for a country that has a register, the 503 (either upstream code) ends with National register fallback (10 EU countries) is available on Pro and Business plans. Countries without a register get the plain error. Paid callers can turn the step off per request with fallback=false, and a request that carries requester_vat_number skips it by default (see Consultation numbers). A fallback response looks like a live one, except that source names the national register, source_status is "fallback", and there is never a consultation_number (national registers cannot issue one, which is why a request with requester_vat_number only takes a register answer when it passes fallback=true):
request_duration_ms includes the VIES attempts that failed before the register was consulted. The result is stored like any other, so the next request for the same number is a cache hit with source_status: "cached" and source: "anaf", and that cache hit triggers a background VIES refresh. Only a confirmation is served. When the register reports the number as not registered or has no record of it, Avatcado falls through to the most recent stored result (source_status: "unavailable", stale set by age) because national registers leave out entity types VIES covers. See National registry fallback. If a member state is unavailable, the national register does not confirm the number (or the country has none), and no stored result exists, the API returns a 503 error with code upstream_member_state_unavailable.

Non-EU validations

CH, LI, NO, and AU validations follow the same 25-day cache policy as EU and UK validations. Caching is especially important for Swiss and Liechtenstein validations because the BFS UID Register enforces a strict 20 requests per minute rate limit. Cached results help you avoid hitting this upstream limit.

Force refresh

Pass cache=false to bypass the cache and fetch a fresh result from the upstream service:
The fresh result is written to cache, so subsequent requests (without cache=false) will use it for the next 25 days. Force-refresh requests count toward your monthly quota like any other request. If the upstream service is unavailable during a force-refresh, the API falls back to the most recent cached result (with meta.stale: true), the same as a normal request, unless the request carries requester_vat_number (see the next section).

Consultation numbers

A request that carries requester_vat_number wants a consultation number, and only a fresh VIES or HMRC check can issue one. Such a request therefore defaults to cache=false and fallback=false: the cache is not read, a VIES outage is not answered from a national register (register answers never carry a consultation number), and no stored result is served at all, not even the most recent one during an outage. The answer is a fresh check or a refunded 503.
curl
When the member state is down, the 503 (upstream_member_state_unavailable, or upstream_unavailable when VIES itself failed) ends with The national register was not consulted because requester_vat_number was supplied. Pass fallback=true to accept a register answer, which never carries a consultation_number. The request is refunded; retry once the member state is back. Both flags remain explicit overrides next to a requester:
  • fallback=true accepts a register answer during a VIES outage. It comes back with source_status: "fallback" and no consultation_number, so treat it as “retry later” when you need the proof.
  • cache=true restores the cache: a result stored for the same requester is served as a cache hit with its consultation number (up to 25 days old), and during an outage the most recent stored result is served with source_status: "unavailable".
  • fallback=false is still accepted as the explicit form, and is the way to skip the register on a request without a requester. It is available on Pro and Business plans and is accepted but ignored on Free, which never consults a register.
On batch and async requests both flags are boolean body fields with the same meaning, and the requester applies to every item. Requests without requester_vat_number are unchanged: the cache is on, the register step runs on Pro and Business, and an outage is answered from the most recent stored result. Note the asymmetry: cache=false without a requester still serves a stored result during an outage, cache=false with a requester does not.

Batch caching

In batch responses, cache information appears per-item in each result’s meta object. Each item in a batch may have a different cache state. One may be a fresh lookup while another is served from cache.
The cache parameter in the request body applies to all items in the batch. Setting cache: false forces fresh lookups for every VAT number. The fallback field works the same way: fallback: false stops every item from consulting a national register during a VIES outage. A requester_vat_number on the batch turns both off for every item, and no item is served from a stored result, unless the body sets the flag to true (see Consultation numbers).