TUTORIAL
Verify a receipt you were given
A vendor, an agent, or another team hands you a Decision Receipt and says the action behind it was checked. This tutorial walks through bounded checks and the separate trust decisions required before relying on that record.
By the end you will have run a one-line issuer-operated check, obtained public-key material for a bounded offline check, and worked through the assumptions to verify before relying on a receipt. Everything here uses the live, public Decision Receipt API at https://decrec.summitcognitive.ai.
1. What you have
A Decision Receipt is a JSON object. You may have received it as a file, pasted into a ticket, or attached to a pull request. Whatever the wrapper, the shape is the same — a record of one evaluated action, with its evidence, policy result, replay result, and an Ed25519 attestation:
receipt.json (abridged)
{
"receipt_id": "dr-...",
"admissibility": { "status": "ACCEPTED" },
"subject": { "agent": "claude-code", "repository": "acme-corp/widget-api", "pull_request": 42 },
"evidence": { "source_count": 2, "source_types": ["ci", "code_review"] },
"replay": { "deterministic": true, "replay_hash": "sha256:..." },
"policy": { "status": "PASS", "checks": [] },
"attestations": [
{ "signer": "decrec-server", "algorithm": "Ed25519", "signature": "base64...", "timestamp": "..." }
],
"chain": { "sequence": 1, "previous_receipt_hash": null }
}
You do not need to understand every field to verify it. For the full breakdown of each section, see the Decision Receipt anatomy. Save what you were given as receipt.json and continue.
2. Quick online check
The fastest way to test a receipt is to ask the issuer to re-verify it. POST /v1/verify takes the full receipt as its request body and requires no API key — anyone can call it.
REQUEST
curl -s https://decrec.summitcognitive.ai/v1/verify \
-H "Content-Type: application/json" \
-d @receipt.json | jq .
RESPONSE
{
"valid": true,
"receipt_id": "dr-...",
"admissibility": "ACCEPTED",
"verification_depth": "cryptographic",
"checks": [
{ "name": "hash_integrity", "status": "PASS", "detail": "Hash abc123... matches ledger" },
{ "name": "signature_valid", "status": "PASS", "detail": "Ed25519 verified" }
]
}
Read the response carefully:
validistrueonly when every check passes. A single failure flips it tofalse.admissibilityechoes the receipt's status — you want ACCEPTED.verification_depthof"cryptographic"means this was not a shape-only check: the canonical hash was recomputed and the signature was validated.checks[]itemizes the issuer-operated work.hash_integrityis consistency with the issuer's ledger view;signature_validis validity under selected key material. Neither proves independent key ownership or unsigned chain position.
This check is fast but issuer-operated. If your relying-party policy requires separation from the live issuer, use the bounded offline path in step 3 and establish the key fingerprint independently.
3. Bounded offline check
A bounded offline check lets you verify the receipt's defined signed content without asking the live issuer to perform that check. The attestation is an Ed25519 signature over that signed representation, not every field in the receipt, and the matching public key is published.
Fetch the issuer's public key once:
REQUEST
curl -s https://decrec.summitcognitive.ai/v1/keys/server > server-key.pem
The endpoint returns the server's Ed25519 public key as PEM text. Before relying on it, obtain and pin the key through a separate trust channel; a key downloaded from the same service as the receipt does not establish signer identity by itself. Then take the receipt's signed content and the signature from its attestations[] entry and check them with a standard Ed25519 verifier. A valid result binds the record to the holder of the corresponding private key and detects later modification; it does not establish action execution or issuance completeness.
Because the key is published separately from any single receipt, you can pin, store, and reuse it. Before relying on the result, authenticate that fingerprint through a trusted channel separate from the receipt and account for the exact verifier version, JSON parsing behavior, and signed-field scope.
For a deeper walkthrough of online versus offline verification and how to pin the public key, see Verifying receipts.
4. What to actually check before trusting
A passing signature tells you that the defined signed content is unmodified under the authenticated, pinned key. It does not authenticate unsigned fields or, by itself, tell you the underlying action met your bar. Before you rely on a receipt, work through this checklist:
- Admissibility is ACCEPTED. Confirm
admissibility.statusis ACCEPTED — not NON_DETERMINISTIC (the action could not be shown to replay to the same result) or REJECTED. Only ACCEPTED receipts cleared the full bar. - The policy verdict. Check
policy.statusisPASS, and read the verdict on the action itself — ALLOWED, ESCALATED, or BLOCKED. An escalated or blocked action may still carry a valid receipt; the receipt records the verdict, it does not override it. - The evidence meets your bar. Look at
evidence.source_countandevidence.source_types. Decide whether the number and kinds of sources (CI, code review, test results, human approval, and so on) are enough for the decision you are about to make. Two sources of one type is a weaker basis than two independent types. - The signature verifies. The
signature_validcheck passed in step 2, and — for separation from the live issuer — your offline check in step 3 confirmed the same signed content against a separately authenticated, pinned key.
If all four hold, you have authenticated the receipt's signed content under your pinned key, confirmed the recorded admissibility and policy fields you evaluated, and judged the cited evidence sufficient for your use. Unsigned fields and action execution remain outside that signature result.
5. Why this matters
A bounded offline check lets a recipient reproduce signature validation without calling the issuer. Independence still requires controlled verifier bytes, controlled JSON input, explicit signed-field scope, and a trust-key fingerprint established separately from the supplier.
The offline path lets you reproduce a particular signature and commitment check without calling the live issuer. It does not eliminate trust: you still rely on authenticated key ownership, exact verifier behavior, controlled input interpretation, and the truth of any recorded evidence.
For the formal meaning of the admissibility states you checked in step 4, see Decision admissibility. To set up your own verification habit end to end, continue with Verifying receipts.