akwitoEU VAT proof

Audit file export

GET /v1/exports/dossier.zip?from=YYYY-MM-DD&to=YYYY-MM-DD&lang=fr
GET /v1/exports/dossier.zip?from=YYYY-MM-DD&to=YYYY-MM-DD&vat_number=FR40303265045

Returns every proof of a period in one streamed ZIP archive — the *dossier de contrôle*, the file an auditor asks for. The dashboard serves the very same archive at GET /app/exports/dossier.zip under a session.

from and to are required calendar dates in UTC, both included. The lang parameter picks the language of the PDF attestations, fr (the default) or en; the readme inside the archive is bilingual either way.

vat_number, when given, restricts the archive to one counterparty: every check of that number in the period, and nothing else. The number is normalised like everywhere else (fr 40303265045 is FR40303265045); a number whose format is not recognised is a 400. A counterparty's history spans years, so the 366-day cap does not apply to this form — only the 10 000-check cap does. The dashboard offers this archive from the number's history page (/app/numbers/{vat}).

The archive is named akwito-dossier-<from>-<to>.zip — or akwito-dossier-<vat_number>-<from>-<to>.zip for one counterparty — and contains:

EntryContents
LISEZMOI.txtwhat the file is, the period, how to verify it — in French, then in English
index.csvone row per check, ; separated, UTF-8 BOM, CRLF, oldest first
attestations/<date>-<vat_number>-<check_id>.pdfthe PDF attestation of each check — the stored time-stamped document when it has one, otherwise a plain rendering
horodatages/<check_id>.tsrthe RFC 3161 timestamp token, when the check has one
ancrages/<YYYY-MM-DD>.jsonthe day's anchor: root, leaf count, authority, signed_at, token
ancrages/<YYYY-MM-DD>.tsrthe raw RFC 3161 token of that day's root
ancrages/chemins/<check_id>.jsonthe inclusion path of a check, the same JSON as GET /v1/checks/{id}/anchor
manifeste.txtone sha256 path line per entry, then a root hash line; checked with sha256sum -c manifeste.txt

index.csv columns:

check_id;vat_number;country;checked_at;valid;confidence;vies_request_id;vies_consulted_at;response_sha256;timestamp_at;timestamp_authority;pdf;tsr;public_url;anchor_day;anchor_root;anchor_leaf_index;pdf_timestamped

The three anchor columns are empty while the check's day is not anchored yet. pdf_timestamped is true when the archived attestation is the stored document carrying its PAdES document time stamp, false when the check has never been downloaded in this language and the attestation is a plain rendering — an export of 10 000 attestations does not call the authority 10 000 times.

The archive carries no generation date and its entries are dated from the data itself: the same period always produces the same bytes, as long as no attestation was downloaded for the first time in between — that first download replaces a plain attestation with its stored, time-stamped one, and pdf_timestamped says which is which.

Limits: a period of 366 days at most (lifted for one counterparty), and 10 000 checks at most. Both are checked before the first byte is written, so an oversized request gets a clean 400 rather than a truncated file. A period with no check is not an error: the archive is valid and holds LISEZMOI.txt, an index.csv with its header alone, and manifeste.txt.

HTTP statuserror.codeWhen
400BAD_REQUESTfrom or to missing or not a YYYY-MM-DD date, to before from, a period over 366 days (without vat_number), or a vat_number whose format is not recognised
400EXPORT_TOO_LARGEthe period holds more than 10 000 checks; narrow it down
409EXPORT_IN_PROGRESSan audit file is already being built for this account; wait for that download to finish

Only one audit file at a time per account, dashboard and API together: a second simultaneous call answers 409 EXPORT_IN_PROGRESS instead of starting a second archive.

A large archive takes minutes to build. Should the connection be cut mid-way, the download is incomplete: check the archive against its own manifeste.txt before filing it.