Archive
Fiscal archive restitution: the exact transmitted bytes of your e-invoicing documents, their SHA-256 manifest, their audit trail, and the export that packages all three.
Show the state of this organization's fiscal archive
GET /api/v1/archive
Requires authentication (Bearer token) and the X-Organization-Id header.
What the fiscal archive does for this organization. state is vault (the paid ArchiveVault: every transmitted byte written to a locked, retention-governed bucket), france_capture (the French transmission capture, which does not depend on the vault) or none; entitled says whether the current plan includes the vault, and plans_with_vault names the plans that do, for an organization that does not have it yet. vault_status (provisioning, active, retained, error) reports a vault that is being set up or wound down.
The rest is what an auditor asks for: region — where the bytes physically live; retention_days — the object-lock retention the storage bucket itself enforces, which is why an archived object cannot be altered or deleted before it lapses; locked; object_count; and last_proven_at / integrity_state (never, running, passed, failed, inconclusive, or not_applicable for an organization that archives nothing) from the platform's own periodic re-verification of every stored hash.
quota_bytes and used_bytes are METERED, never enforced: exceeding the quota drops nothing. (#980)
Responses
| Status | Description |
|---|---|
| 200 | For non-paginated data, return as before |
| 422 | |
| 403 |
Example request
curl -X GET "https://kworia.com/api/v1/archive" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
List the archived objects (the manifest index)
GET /api/v1/archive/documents
Requires authentication (Bearer token) and the X-Organization-Id header.
The paginated index over the archive's manifest, most recently archived first.
Each row is one archived OBJECT, not one document. A single invoice normally contributes several — the request body sent to the e-invoicing provider, the response it returned, the UBL XML, the PDF, each attachment, the webhook events and the delivery evidence — and each carries its own id, its own object_kind and its own sha256. That sha256 is the fingerprint of the exact bytes GET /api/v1/archive/documents/{id}/download returns, so a recipient can recompute it and prove the archive did not alter what was transmitted.
Filters: number and counterparty (partial, case-insensitive), issued_from / issued_until (the document's issue date), amount_min / amount_max, direction (outbound, inbound), kind (request_body, response_body, ubl_xml, pdf, attachment, webhook_event, received_document_json, status_snapshot, evidence), plus per_page (1–200, default 25) and page.
Amounts are strings, never floats — an index that rounded a total is an index an auditor can disprove. The storage address (bucket, storage account, object key) is deliberately absent here; the export's manifest.csv carries it for an auditor who needs it. (#980)
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
number |
query | string | no | |
counterparty |
query | string | no | |
issued_from |
query | string | no | |
issued_until |
query | string | no | |
amount_min |
query | number | no | |
amount_max |
query | number | no | |
direction |
query | string | no | |
kind |
query | string | no | |
per_page |
query | integer | no | |
page |
query | integer | no |
Responses
| Status | Description |
|---|---|
| 200 | For non-paginated data, return as before |
| 422 | |
| 403 |
Example request
curl -X GET "https://kworia.com/api/v1/archive/documents" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Download one archived object, byte for byte
GET /api/v1/archive/documents/{id}/download
Requires authentication (Bearer token) and the X-Organization-Id header.
The archived bytes of one object, streamed back exactly as they were stored — nothing is re-generated, re-encoded or re-signed. Content-Type is the manifest row's content_type and Content-Length its size_bytes, so the response can be hashed and compared with the row's sha256. {id} is the id of a row from GET /api/v1/archive/documents.
404 for an identifier that is not in your organization's archive — the same answer as for one that does not exist at all, so an identifier cannot be tested for existence. 503, never 404, when the archive cannot produce bytes the manifest names: that is an integrity incident rather than a missing page, the platform's integrity check is alerted, and reporting it as "not found" would hide it.
Every successful download is appended to this organization's audit chain, naming the user and the surface. (#980)
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | yes |
Responses
| Status | Description |
|---|---|
| 503 | The archive could not produce the bytes this manifest row names. The platform's integrity check has been alerted. |
| 404 | No archived object with that identifier — including one that belongs to another organization. |
| 200 | The archived bytes, with the manifest row's own content type and length. |
| 422 | |
| 403 |
Example request
curl -X GET "https://kworia.com/api/v1/archive/documents/{id}/download" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Order an export of the archive (ZIP)
POST /api/v1/archive/exports
Requires authentication (Bearer token) and the X-Organization-Id header.
Orders one ZIP containing the archived objects, their manifest, the audit trail and the network exchanges. 202, not 201: the build runs asynchronously on the archive queue, so what exists when this returns is the work order (status: pending) and not yet the artifact — poll GET /api/v1/archive/exports/{id} and collect it when download_url is no longer null.
An empty body means the whole archive. Otherwise the same eight clauses as GET /api/v1/archive/documents narrow it (number, counterparty, issued_from, issued_until, amount_min, amount_max, direction, kind); there is no paging, because an export walks the whole matching set. The set is fixed at the instant the export is ordered, so documents archived while it builds are not silently added to it.
Only one export builds at a time per organization. A second request while one is pending or building is refused with 409, as is a request whose filters match nothing. One ZIP also packages a bounded number of objects — 72 000 by default, derived from what a single build can hold in memory and finish inside its time budget — and a request covering more is refused with the same 409 rather than accepted and failed an hour later; narrow it with issued_from/issued_until, one financial year per export. The finished artifact expires — seven days by default — and is then deleted from the operational disk, because a copy of a decade of counterparties and amounts must not sit outside the locked vault indefinitely.
Requires the archive.export permission (and an API token carrying the archive.export scope). Unlike every other write on this API, this endpoint stays available to an ARCHIVED organization: it mutates no business record, and an archived organization is precisely the one that most needs its fiscal records handed back. (#980)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
number |
string | no | |
counterparty |
string | no | |
issued_from |
string | no | |
issued_until |
string | no | |
amount_min |
number | no | |
amount_max |
number | no | |
direction |
string | no | |
kind |
string | no |
Responses
| Status | Description |
|---|---|
| 202 | The work order was accepted. The ZIP does not exist yet. |
| 403 | |
| 409 | An export is already being assembled for this organization, the filters match nothing to export, or the request covers more objects than one export may package. None of the three is an authorization failure. |
| 422 |
Example request
curl -X POST "https://kworia.com/api/v1/archive/exports" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"number": "string",
"counterparty": "string",
"issued_from": "string",
"issued_until": "string",
"amount_min": 1,
"amount_max": 1,
"direction": "string",
"kind": "string"
}'
Show one export and where to collect it
GET /api/v1/archive/exports/{id}
Requires authentication (Bearer token) and the X-Organization-Id header.
The state of one work order: status (pending, building, completed, failed, expired), object_count — what the build actually packaged — and, separately, missing_object_count, because folding a shortfall into the count would make a partial restitution read exactly like a complete one. Also file_size_bytes, manifest_sha256, the filters the export was ordered with, and expires_at.
Once there is something to collect, download_url addresses GET /api/v1/archive/exports/{id}/download — authenticated by the same bearer token as every other operation here. It is not the signed browser link the notification email carries: that one sits behind the session guard and a bearer token presented to it is a redirect to the login page. While there is nothing to collect, download_url is null.
The ZIP contains, per spec §3.8: objects/<object key> — the archived bytes themselves; manifest.json and manifest.csv — one record per object with its SHA-256, bucket, storage account, region, size and present_in_export; audit-trail.json and audit-trail.csv — this organization's append-only hash chain, exported WHOLE even for a filtered export, because a chain can only be verified end to end; transmissions.json and transmissions.csv — every exchange with the e-invoicing network or the tax authority, joined to the trail on the document identifier and including the French e-reporting submissions that belong to no single document; and a bilingual FR/EN README telling the recipient how to recompute the hashes themselves.
404 for an identifier outside your organization. (#980)
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Responses
| Status | Description |
|---|---|
| 200 | For non-paginated data, return as before |
| 404 | No export with that identifier — including one that belongs to another organization. |
| 422 | |
| 403 |
Example request
curl -X GET "https://kworia.com/api/v1/archive/exports/{id}" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Download a finished export (ZIP)
GET /api/v1/archive/exports/{id}/download
Requires authentication (Bearer token) and the X-Organization-Id header.
The ZIP itself — the address download_url points at — authenticated by the same bearer token as every other operation here, which is why it carries no signature.
404 for an identifier outside your organization and for an export that is not ready (one answer for "not yours", "no such export" and "not finished"). 410 once expires_at has passed: the artifact was deliberately deleted from the operational disk, and the next step is to order another one — which "not found" would not tell you. 503 if the row is complete but the artifact is not on the disk; the platform's integrity check is alerted.
Each successful download is appended to this organization's audit chain, naming the acting user and recording which door was used — the handover is itself part of the evidence a tax inspector may be shown. (#980)
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Responses
| Status | Description |
|---|---|
| 503 | The export is recorded as complete but its artifact could not be read. The platform's integrity check has been alerted. |
| 410 | The export's deadline has passed and the artifact was deleted. Order another one. |
| 404 | No export with that identifier — including one that belongs to another organization, and one that is not ready. |
| 200 | The export archive. |
| 422 | |
| 403 |
Example request
curl -X GET "https://kworia.com/api/v1/archive/exports/{id}/download" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"