When a Caddie seller grants our support team temporary access to their account, every action taken inside that account is written to a record the seller can read and download. This page explains how to check that record independently, without our help and without needing to trust us.

That last part is the point. A record that only its keeper can vouch for is not much of a record.

What the record covers

One entry is written for every action Caddie Support takes inside a seller's account: what was changed and from what value to what value, items created or deleted with all their fields, bulk operations with the affected item ids, and attempts that were refused by our own restrictions, such as anything touching billing, passwords or API keys. Refused attempts are recorded on purpose. A record containing only what succeeded has a hole in it exactly where someone would want to look.

Ordinary reads are not all recorded, and machine keepalives are excluded. Entry into the account is always recorded.

The two things you check

  1. That an entry has not been altered since it was written. Each entry carries the exact text it was built from, plus a SHA-256 fingerprint of that text taken at the moment it was written.
  2. That the fingerprint existed when we say it did. Fingerprints are published to a public Hedera Consensus Service topic, which timestamps and orders them independently of Caddie. Publishing happens moments after an entry is written, never as part of writing it, so a very recent entry may not be on the topic yet. Any entry not yet published is marked pending in your record and carries no Hedera timestamp. See "Checking the fingerprint against Hedera" below.

The canonical form

The fingerprint is a SHA-256 digest, lowercase hex, of a single UTF-8 string. That string is a JSON object with exactly these nine fields, keys sorted alphabetically, no whitespace between tokens:

FieldMeaning
actorAlways Caddie Support. Support is recorded as the company, not as an individual.
created_atUTC, ISO 8601, no timezone suffix. Microseconds are omitted entirely when zero.
grant_idThe specific permission the seller gave, under which this action was taken.
methodHTTP method.
routeThe route template, not the concrete URL.
status_codeHTTP status. 403 means our own restrictions refused the attempt.
summaryThe plain-language description of what happened.
target_idThe affected record, or null.
user_idThe seller's account.

You do not need to build this string yourself. Every entry in the downloaded file already contains it verbatim, as canonical_payload. Rebuilding it by hand is the one way to get a wrong answer, so the file hands you the exact bytes instead. The format is documented here so you can confirm we are not hiding anything in it, not so you have to reproduce it.

Worked example

An entry recording a price change from $40.00 to $25.00. This is the exact canonical_payload string:

{"actor":"Caddie Support","created_at":"2026-08-09T18:52:14.203871","grant_id":"7c1f0f4e-6a2b-4f13-9c8d-2a5b7e91d004","method":"PUT","route":"/api/inventory/{item_id}","status_code":200,"summary":"Edited an item: price_cents 4000 -> 2500","target_id":"e58c2f90-1d34-4b77-8a05-6f2c9b13de47","user_id":"b3d9a1c2-5e47-4a8f-9d21-0c6f4b7e2a38"}

Its SHA-256 digest, which is the content_hash stored on that entry:

21d38eb08759e8e61c204813063f73ee4e395d61b8b99754d4e9735fb4afa500

Checking it yourself

Command line

printf '%s' 'PASTE_THE_canonical_payload_HERE' | shasum -a 256

Use printf rather than echo. echo adds a trailing newline on most systems and will give you a different digest.

Python, checking a whole downloaded file at once

import hashlib, json

doc = json.load(open("caddie-support-record.json"))

for grant in doc["grants"]:
    for a in grant["actions"]:
        if not a["verifiable"]:
            print("SKIP (no checkable text stored):", a["summary"])
            continue
        digest = hashlib.sha256(a["canonical_payload"].encode("utf-8")).hexdigest()
        status = "OK" if digest == a["content_hash"] else "MISMATCH"
        print(status, a["at"], a["summary"])

Every entry should print OK. A MISMATCH means that entry's contents differ from what was fingerprinted when it was written.

Checking the fingerprint against Hedera

An entry is fingerprinted first and published second. Publishing never delays or blocks a seller's own data, so an entry can exist and be checkable before its fingerprint has reached the topic. Entries awaiting publication are marked pending in the downloaded record and carry no sequence number, no consensus timestamp and no mirror node link. A pending entry still passes the first check above. It simply has no independent timestamp yet.

Fingerprints are submitted to a single Hedera Consensus Service topic on mainnet:

NetworkHedera mainnet
Topic0.0.10802877
Browsehashscan.io/mainnet/topic/0.0.10802877
Raw messagespublic mirror node

To check one specific entry, take its anchor.mirror_node_url from the downloaded record and open it. The message field is base64. Decode it, and it must equal that entry's content_hash exactly. The consensus_timestamp in that response is the network's own, to the nanosecond, and must match the entry's anchor.consensus_timestamp digit for digit. We publish the timestamp in the network's exact form rather than a rounded one, so there is nothing to reconcile.

The topic was created with no admin key. On Hedera that is permanent and publicly checkable: the topic can never be modified or deleted by anyone, including Caddie, and including if we were ordered to. You can confirm this yourself. Open the raw link above and look for "admin_key": null. Anyone may also pay to extend the topic's expiration, so a seller or their lawyer can keep this evidence alive without our cooperation.

What this proves, and what it does not

This record is tamper-evident. It is not tamper-proof, and we will not describe it that way.

We would rather state the limit plainly than let a seller or a court discover it later.

If something does not check out

If an entry shows MISMATCH, or an entry you expected is missing, contact support@getcaddie.now. Keep your downloaded file. It is your copy and it does not depend on us continuing to hold anything.

Canonical form v1. If this format ever changes, it will be published as a new version anchored to a new topic, never edited in place, because changing it would invalidate every fingerprint already published under it.