Spec v1.0.0

The export format is public. On purpose.

Every AssetDNA organisation can download its complete operating record as one open JSON file — assetdna.export.v1 — and anyone can verify that file offline, without AssetDNA existing. This page and the machine-readable schema below are the whole contract. If we ever disappeared, raised prices, or misbehaved, your record walks out the door intact and provable. That is the point.

The integrity model in one paragraph

Every change to the record is an event in an append-only chain. Each event's hash commits to the previous event's hash, so history can't be rewritten without breaking every hash after the edit. Head hashes are periodically anchored with an independent RFC 3161 timestamp authority, so the history provably existed — even we can't back-date it. Since 2026-09-22 every head anchored in a night is a leaf of one RFC 6962 tree: the root is stamped once per authority, the export keeps the head's inclusion path, and every night's root, its leaf list and its receipts are public at /api/roots. Documents are bound in by SHA-256 fingerprint. The export carries all of it.

Hash rule

hash    = sha256( prevHash | type | payload | at(ISO) | propertyId )
genesis = "0000000000000000000000000000000000000000000000000000000000000000"

payload is hashed VERBATIM as the JSON string in the file — do not parse
and re-serialise it. at is hashed in ISO-8601 form. A null propertyId
hashes as the empty string. Field separator is "|".

Verification recipe

  1. Sort events by seq ascending; confirm seq is contiguous from 1.
  2. Start with prev = genesis. For each event: confirm prevHash === prev, re-derive the hash with the rule above, confirm it equals the event's hash, then set prev to it.
  3. Confirm the final prev equals integrity.headHash.
  4. Optionally, verify each anchor's RFC 3161 token (downloadable per-anchor) against its headHash with the authority's public certificate — proof of existence at the signed time, independent of AssetDNA.
  5. Where an anchor carries root, leafIndex, treeSize and path, the token is over the root: re-derive the leaf as SHA-256(0x00 ‖ ASCII hex of headHash), walk the path (node = SHA-256(0x01 ‖ left ‖ right), split at the largest power of two below n) and confirm the root; then verify the token against the root. /verify does the first half offline; /api/roots lets you rebuild the whole night's tree.
  6. The file's receipts carry each authority's receipt over the latest root: verify the RFC 3161 token against the root with the authority's certificate (openssl ts -verify), or the Rekor entry at the log. Since every root carries the previous one as leaf 0, that one receipt set covers every anchor in the file — nothing fetched from anyone.
  7. For any document you hold the bytes of, confirm its SHA-256 equals the record's sha256.

Steps 1–3 run in any language in ~20 lines with a SHA-256 primitive — or paste the file into the in-browser verifier, which does exactly this with Web Crypto and no upload.

Field reference

FieldTypeMeaning
format"assetdna.export.v1"Format discriminator. Version-suffixed; breaking changes mint a new value.
exportedAtstring (ISO-8601)When this file was produced.
orgobjectname, slug, reportingCurrency (ISO 4217) of the exporting organisation.
integrityobjectThe exporter's own audit at export time: chainVerified, events (count), genesis, headHash, hashRule. Recompute it yourself — never take this object on trust.
propertiesobject[]The operating record: units, leases, valuations, meter readings, incidents, compliance. Convenience data — the events chain is the authoritative history.
eventsobject[]The full hash chain, ascending contiguous seq from 1. Each event: seq, type, payload (a JSON string — hashed verbatim), at, actor, source, propertyId, prevHash, hash.
receiptsobject | nullThe authorities' receipts over the latest platform root this record was anchored under: provider, signed time, token. One receipt set covers every anchor in the file, because every root commits to the one before it.
anchorsobject[]External RFC 3161 timestamps over head hashes: atSeq, headHash, tsaProvider, tsaTime — and, on a root anchor, root, leafIndex, treeSize and path (the token is over the root; the path proves the head is a leaf of it). Independent third-party proof the history existed by a point in time.
documentsobject[]Document metadata + SHA-256 fingerprints: kind, filename, sha256, sizeBytes, uploadedBy, uploadedAt. Raw bytes download separately; the hash binds them to the record.

The strict contract is the chain-critical structure (integrity, events, anchors, documents); properties is deliberately open and may grow fields without a version bump. The authoritative machine-readable definition is the JSON Schema (draft 2020-12).

Versioning promise

assetdna.export.v1 is frozen: fields may be added, never removed or changed in meaning, and the hash rule never changes within v1. A breaking change mints assetdna.export.v2 alongside — v1 files stay verifiable forever, because a proof that expires is not a proof.