Submit up to 50 000 EU VAT IDs for background validation
Records the batch and answers 202 Accepted with a job id. Nothing is validated during this request – the positions are worked through in the background and read back through the three endpoints below.
This is why the endpoint is asynchronous: a cold-cache VAT ID costs a real VIES round trip, so even a hundred of them cannot honestly be answered inside one HTTP request, let alone fifty thousand. A job runs at a deliberately limited concurrency – five checks at a time, whatever the batch size – and steps aside from member states VIES is currently struggling with, so a batch takes a bounded share of upstream capacity rather than as much as it can get. There is no priority queue: your live GET /v1/vat/{vatId} calls are not routed ahead of your batches, they simply are not competing with an unbounded one. Stepping aside applies to the affected positions only: the job keeps working every other member state in the batch and comes back to the degraded one later. If it is still degraded when the job runs out of retries, ONLY that member state’s positions are answered VIES_UNAVAILABLE – a position is never given an error for a check that was not attempted.
Duplicates are collapsed. VAT IDs are normalised (trimmed, uppercased, whitespace, - and . removed) and de-duplicated, preserving first-seen order, so a list containing the same ID twice produces ONE position and is charged ONE quota unit. duplicatesDropped reports how many entries that removed.
Send an Idempotency-Key. It is optional, and this is the endpoint where it matters most: if the connection drops before the 202 arrives, you cannot tell whether up to 50 000 billable positions were accepted, and a plain retry buys them twice. Repeating the request with the same key AND THE SAME LIST OF VAT IDS returns the SAME job – no second job, no second charge. Keys are scoped to your account; a key you have not used before starts a new batch. Repeating a key with a DIFFERENT list is rejected with 409 IDEMPOTENCY_KEY_CONFLICT rather than silently answered with the old job (which would hide part of the new batch) or bought as a second job (which would defeat the key). 8–200 characters of letters, digits, ., - or _; a key that does not parse is refused with IDEMPOTENCY_KEY_INVALID rather than ignored, because ignoring it would leave you believing you were protected.
Quota is spent per position, as it is answered, exactly as on the single-ID endpoint – not reserved for the whole batch up front. A position that ends in an upstream error is refunded, and so is one whose answer could not be stored. That per-position accounting has one gap: if the process running the job dies between reserving a position’s quota and recording its answer, the reservation is not returned. The position stays pending, is answered again when the job resumes, and its quota unit is spent twice – bounded by the five positions a pass works on at once, so a crash costs at most a handful of positions, not the batch. What running out of quota mid-job does depends on the plan: a plan with overage enabled keeps going and bills the extra positions at its overage rate, while a hard-capped plan answers every remaining position with RATE_LIMITED. Either way the job finishes.
In test mode (a vat_test_ key) the job is real and the polling contract is identical, but every position must start with XX and is answered from fixtures – no quota, no VIES call, no stored check.
Jobs and their positions are kept for 30 days (expiresAt), after which they are deleted. The checks themselves live on under their own checkId in your check history.
Request
- Base URL: https://api.vatnode.dev
- URL: https://api.vatnode.dev/v1/vat/bulk
- Auth: HTTP bearer
Headers
Mint one per batch you intend to submit (a UUID is ideal) and resend it verbatim, with the same vatIds, on any retry. The same key and batch always resolve to the same job; the same key with a different batch is a 409, not a silent mismatch.
Request body
Example request
{
"vatIds": [
"IE7654321A"
]
}Response
The batch was recorded. Poll the job for progress. A repeat of a request that carried an Idempotency-Key and the SAME vatIds answers 202 with the job that key already created – status and the counters are then whatever that job has reached by now, not recomputed from this request, and not necessarily queued.
Changes
No recorded changes to this operation across all 1 revision of this API.