GUIDE
Verifying receipts
A Decision Receipt is only useful if its commitments and signature can be checked against trust material established separately from the receipt. This guide distinguishes the issuer-operated POST /v1/verify endpoint from a bounded offline signature check and states what neither path proves.
JavaScript CLI 0.1.0/0.1.1 and Action 0.1.0/0.2.0 are withdrawn. Use checksum-pinned CLI 0.1.4 (d6763fdc…4c31), Action 0.2.3 (39b50ef6…2ed4), or Python verifier 1.3.0 (6b48d7a7…7a47). The current JavaScript releases reject malformed Ed25519 keys, return UNVERIFIED for unsigned legacy cross-receipt linkage, and refuse duplicate object keys and integers outside the exactly representable range in receipt, pinned-keyring, and JSON-typed SCITT payloads. They also reject malformed UTF-8 and unsupported compressed JSON Content-Formats in SCITT payloads. CLI 0.1.3 and Action 0.2.2 are superseded because their SCITT verification path could discard a strict-JSON failure; earlier JavaScript releases and Python 1.1.0 are also retired or superseded. Read the exact hashes and relying-party guidance.
Online verification
The simplest way to verify a receipt is to send it back to the API. Take the receipt object returned by POST /v1/evaluate, save it as a file, and POST it to /v1/verify. This endpoint requires no authentication — anyone holding a receipt can check it.
REQUEST
curl -s https://decrec.summitcognitive.ai/v1/verify \
-H "Content-Type: application/json" \
-d @receipt.json | jq .
The response reports an overall verdict and the individual checks that produced it:
RESPONSE
{
"valid": true,
"receipt_id": "dr-...",
"admissibility": "ACCEPTED",
"verification_depth": "cryptographic",
"checks": [
{ "name": "receipt_id_valid", "status": "PASS" },
{ "name": "admissibility_present", "status": "PASS" },
{ "name": "replay_present", "status": "PASS" },
{ "name": "policy_present", "status": "PASS" },
{ "name": "evidence_present", "status": "PASS" },
{ "name": "attestation_present", "status": "PASS" },
{ "name": "hash_integrity", "status": "PASS", "detail": "Hash abc123... matches ledger" },
{ "name": "signature_valid", "status": "PASS", "detail": "Ed25519 verified" }
]
}
The valid field is true only when every check performed by this endpoint passes. If it is false, at least one check failed. A true result is bounded: it reports the checks the issuer-operated service performed; it does not independently establish key ownership, unsigned chain position, source truth, action execution, legal admissibility, or regulatory acceptance. The receipt_id echoes the receipt under test, admissibility reports its recorded status, and verification_depth: "cryptographic" means signature validation was attempted rather than only structural inspection.
The checks[] array is the audit trail of the verification itself. When valid is false, read the array to find which named check returned a non-PASS status and use its detail to understand why.
The three verification layers
Verification proceeds in three layers, each stricter than the last. The checks[] array maps onto them.
- Schema presence. The required fields exist and are well-formed. A receipt missing them is structurally incomplete; their presence alone says nothing about whether the recorded evidence or action is true.
- Hash consistency. The issuer-operated endpoint recomputes the receipt's canonical commitment and compares it with its ledger record. This is a service-side consistency check. Legacy
chain.sequenceandchain.previous_receipt_hashcoordinates are outside the signed core and are not authenticated by the receipt signature. - Signature verification. The Ed25519 attestation is checked against selected public-key material. This confirms validity under that key; it does not prove the key belongs to Summit unless the relying party established that binding independently.
A receipt that clears all three layers passed those named checks. verification_depth: "cryptographic" does not expand the signature's field coverage or convert structural chain coordinates into signed facts.
Offline signature verification against a pinned key
Sending a receipt back to /v1/verify is convenient, but it asks the issuer to assess its own record. An offline check removes the live API from the request path, but it still depends on the verifier implementation, controlled JSON interpretation, and a key whose Summit ownership the relying party established through a separate trusted channel.
The service publishes an Ed25519 public key in PEM format at GET /v1/keys/server. Fetching a key from the same service is not, by itself, an independent identity ceremony; confirm its fingerprint through an approved separate channel before pinning it:
REQUEST
curl -s https://decrec.summitcognitive.ai/v1/keys/server > server-key.pem
RESPONSE
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA...
-----END PUBLIC KEY-----
After independently authenticating and pinning that key, a third party can validate the receipt's signed core with a suitable Ed25519 implementation offline. The check establishes that the signed bytes validate under the selected key. It does not authenticate fields outside the signed core, prove real-world execution, or establish the key's owner.
Why bounded offline verification matters
A relying party should be able to reproduce a cryptographic check without asking the issuer to perform it. That separation is useful only when its assumptions stay explicit: exact verifier bytes, controlled input parsing, the signed-field set, and an independently established trust key. A PASS is evidence for that bounded check, not a general certificate of truth.
Publishing /v1/keys/server makes key material available; it does not itself prove organizational ownership. Preserve an approved fingerprint and the exact verifier hash with the receipt if the result must survive later review.
For the conceptual grounding behind what a receipt captures and why it is structured this way, see the Decision Receipt concept page.