Bulk VAT number validation against the official, keyless VIES REST API. This EU VAT validator accepts numbers in any common format and returns one row each: validity, registered name and address where disclosed, and a clear skip reason. A VIES VAT checker built for whole lists.
Real implementation landed: src/vies_client.py (curl-cffi + explicit
verify=certifi.where() per REQ-10, retry/backoff on 429/5xx and
body-level MS_MAX_CONCURRENT_REQ-style userError codes, never
raises), src/parser.py (glued/spaced/structured input normalisation,
"---" → null for DE/ES, check-status sentinel row), src/main.py
(bounded-concurrency fan-out via asyncio.Semaphore + gather,
per-entry fault isolation, PPE charging on every landed row).
Live-confirmed VIES field names (isValid, name, address,
requestDate, userError) against ms/DE/vat/811907980,
ms/IE/vat/6388047V, ms/NL/vat/810462215B01, ms/ES/vat/A28017895,
and check-status (2026-09-06).
56 unit/integration tests (models, parser, vies_client retry/backoff,
main fault isolation, PPE charge regression) + 1 opt-in live smoke
test against the input_schema.json prefill. ruff/pyright clean.
Added promo.json (GTM manifest) and wove the target keyword set
into README copy.
0.0.1 — 2026-09-06
Scaffold only — no real VIES validation yet.
Scaffolded: .actor/ (actor.json, input/output/dataset schemas,
pay-per-event, Dockerfile), src/main.py (boots, reads input,
validates it via ActorInput, charges actor-start, pushes one
skipped=true placeholder row, and exits cleanly — no real HTTP
call to VIES), src/models.py (ActorInput, VatEntry, ResultRow
per ADR-0004), a smoke test, README skeleton.