Skip to main content
In compliance and audit scenarios, you often need to prove that the identity data you hold has not been tampered with since it was captured. Tally builds a cryptographic hash chain into every subject’s snapshot history: each snapshot records an envelope_hash (the SHA-256 hash of the RFC 8785–canonicalized envelope) and a prev_hash (the envelope_hash of its parent). You can export this entire chain as a single JSON file and verify it offline — without any network access — using the tally verify-ledger CLI command.

Export a subject’s ledger

Call GET /v1/subjects/:subject_type/:subject_id/export to download all snapshots for a subject in a single JSON document. Save the response to a file — this is your audit artifact.
curl "https://api.tally.io/v1/tenants/acme-kyc/subjects/entity/ent_acme_001/export" \
  -H "Authorization: Bearer $TALLY_API_KEY" \
  -o acme_001_export.json
The export file has the following structure:
{
  "subject": {
    "subject_type": "entity",
    "subject_id": "ent_acme_001"
  },
  "canonicalization_method": "rfc8785",
  "hash_algorithm": "sha-256",
  "snapshots": [
    {
      "snapshot_version": 1,
      "snapshot_id": "b1a2c3d4-e5f6-7890-abcd-ef1234567890",
      "envelope": {
        "envelope_version": "entity_state_envelope_v1",
        "snapshot_id": "b1a2c3d4-e5f6-7890-abcd-ef1234567890",
        "snapshot_version": 1,
        "generated_at": "2026-02-18T16:12:00Z",
        "subject": { "subject_type": "entity", "subject_id": "ent_acme_001" },
        "attributes": { ... },
        "evidence": [ ... ],
        "audit": { ... }
      },
      "envelope_hash": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3",
      "prev_hash": null
    },
    {
      "snapshot_version": 2,
      "snapshot_id": "c2d3e4f5-a6b7-8901-cdef-234567890abc",
      "envelope": { ... },
      "envelope_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "prev_hash": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
    }
  ]
}
The export endpoint has a server-configured maximum size. If a subject has more snapshots than the configured limit (1,000 by default), the request returns 400 with a validation_error rather than a truncated result — this prevents you from unknowingly verifying an incomplete chain.

Install the CLI

Install the Tally CLI globally with npm:
npm install -g @tally/cli
Or run it directly without installation using npx:
npx @tally/cli verify-ledger acme_001_export.json

Verify a ledger file

Run tally verify-ledger <path> against your export file:
tally verify-ledger acme_001_export.json
On success, the command prints a confirmation message and exits with code 0:
Ledger verification passed.
On failure, it exits with code 1 and prints one line per error:
Ledger verification failed:
- snapshots[2].envelope_hash does not match computed hash.
- snapshots[3].prev_hash does not match prior envelope_hash.

What the verifier checks

The CLI performs the following checks in order:
1
Subject fields
2
Confirms that subject.subject_type and subject.subject_id are present and non-empty strings.
3
Canonicalization and hash metadata
4
Confirms that canonicalization_method is "rfc8785" and hash_algorithm is "sha-256". If either is wrong, the tool cannot reliably verify hashes and halts.
5
Snapshot ordering
6
Confirms that snapshots are ordered ascending by (snapshot_version, snapshot_id). A gap or out-of-order entry is flagged as a structural error.
7
Envelope hash integrity
8
For each snapshot, re-computes SHA-256(RFC 8785 canonicalize(envelope)) and compares it to the stored envelope_hash. A mismatch means the envelope content was modified after the hash was recorded.
9
Hash chain linkage
10
Confirms that each snapshot’s prev_hash equals the envelope_hash of the preceding snapshot. The root snapshot (version 1) must have prev_hash: null. A broken link means either a snapshot was inserted, removed, or reordered in the chain.

What verification proves

A successful verify-ledger run proves that the export file you hold is internally consistent and has not been tampered with since it was produced. Specifically, it proves:
  • Every envelope’s content matches the hash recorded at write time.
  • The snapshots form an unbroken chain from the root to the most recent version — no version has been silently deleted, reordered, or substituted.
This makes the export suitable for:
  • Compliance audits — provide the export file and a verify-ledger run log as evidence that your identity records are unmodified.
  • Regulatory submissions — demonstrate the provenance and integrity of KYC/KYB data submitted to regulators.
  • Third-party sharing — share an export with a counterparty or auditor who can verify it independently without needing API access to your tenant.
Automate verification in your CI/CD pipeline. Add a step that exports each subject’s ledger and runs tally verify-ledger on a schedule (or after every snapshot write). If the check ever fails, alert your compliance team immediately — a verification failure on a previously clean export is a strong signal that data integrity has been compromised.
# Example CI step
curl "$TALLY_API_URL/v1/subjects/entity/$SUBJECT_ID/export" \
  -H "Authorization: Bearer $TALLY_API_KEY" \
  -o ledger.json

npx @tally/cli verify-ledger ledger.json