Export Bundle Format
The tenant export produces a single zip bundle containing everything a workspace holds: original files, extracted content, structured values with provenance, and the complete audit log, each entry hashed into a manifest so the receiver can verify the bundle file by file. The layout follows the spirit of the BagIt packaging convention: payload directories plus a top-level checksum manifest and a bag-info metadata file. The format is versioned; this page specifies format version 1.
Bundle layout (v1)
| Parameter | Type | Description |
|---|---|---|
| /originals/<docid>-<filename> | payload | The original ingested bytes of each document, named by document ID plus a sanitized filename. |
| /markdown/<docid>.md | payload | The extracted markdown of each document that has one. |
| /values/<docid>.jsonl | payload | One JSON object per line per stored value cell: the latest value-plane cells with provenance for that document. |
| /audit/audit-events.csv | payload | The workspace audit log as CSV (capped at 50,000 rows in v1). |
| /bag-info.json | metadata | Bundle metadata: format version, workspace, generation time, and per-payload counts. |
| /manifest-sha256.txt | manifest | One line per bundle entry: the SHA-256 hex digest, two spaces, the entry path. The manifest itself is the last file added and is not self-referential. |
{
"export_format_version": 1,
"tenant": "<workspace-id>",
"generated_at": "2026-07-18T04:12:09.331Z",
"counts": {
"documents": 3465,
"originals": 3465,
"missing_originals": 0,
"markdown": 3441,
"values": 3390,
"audit_events": 48210
}
}Each line of a /values/<docid>.jsonl file is one value cell with its provenance: record_set_id, layer, record_id, field_key, data_type, the typed value, normalized_value, confidence, status, source, audit_ref, cell_version, and created_at. This gives the receiving system not just the data but where each value stands in the processing lifecycle and which audit reference produced it.
# Enqueue the export (returns the job row)
curl -X POST "$API_URL/records/tenant-export" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Step-Up-Code: 123456"
# Poll until status is completed
curl "$API_URL/records/tenant-export/$JOB_ID" \
-H "Authorization: Bearer $TOKEN"
# → { "status": "completed", "download_url": ".../records/tenant-export/<id>/download",
# "manifest": { "bag_info": { ... }, "bundle_sha256": "…", "bundle_bytes": 1287340032, "entry_count": 10344 } }
# Stream the zip
curl -L "$API_URL/records/tenant-export/$JOB_ID/download" \
-H "Authorization: Bearer $TOKEN" -o export.zipunzip -q export.zip -d export/
cd export/
# Verify every entry against the manifest (GNU coreutils)
sha256sum -c manifest-sha256.txt
# The job status also reports bundle_sha256 over the whole zip:
sha256sum ../export.zipBundles are built asynchronously on the worker fleet and stored server-side; the download streams through the authenticated API (there is no unauthenticated or presigned link). The job status carries the bundle's own SHA-256 and byte size, so the transfer itself is verifiable end to end: verify the zip hash first, then the per-entry manifest inside. Failed jobs stay failed and are re-requested explicitly; a partial bundle is never silently rebuilt over.