Skip to content

Receipt Verification

This guide walks through verifying a SIX receipt step by step. A receipt is valid when the commitment matches the fields and the signature matches the commitment.


Prerequisites

You need:

  • A receipt object (returned from any SIX inference)
  • Your SIX API key (for API verification) or the CLI tool (for local verification)

Step 1: Capture the Receipt

Every inference response includes a receipt. Store it:

response = requests.post(
    "https://six-sov.com/v1/chat/completions",
    headers={"Authorization": f"Bearer {SIX_API_KEY}"},
    json={
        "model": "default",
        "messages": [{"role": "user", "content": "Your prompt"}],
        "privacy_tier": "sovereign"
    }
)

data = response.json()
receipt = data["receipt"]

# Store for later verification
import json
with open("receipt.json", "w") as f:
    json.dump(receipt, f, indent=2)

Your stored receipt looks like this:

{
  "receipt_id": "rcpt_f8c505ce3a7b4d2e9f1a...",
  "routing": "sovereign",
  "commitment": "04a7f3c2d8e6b5a9...e9b1d0f",
  "signature": "0x69c8a3f7...f98c8",
  "verified": true
}

Step 2: Verify via API

The simplest verification path. Send the receipt ID to the verification endpoint:

curl https://six-sov.com/v1/verify/rcpt_f8c505ce3a7b4d2e9f1a \
  -H "Authorization: Bearer $SIX_API_KEY"
receipt_id = receipt["receipt_id"]

verify_response = requests.get(
    f"https://six-sov.com/v1/verify/{receipt_id}",
    headers={"Authorization": f"Bearer {SIX_API_KEY}"}
)

result = verify_response.json()

if result["status"] == "verified":
    print("Receipt verified successfully.")
    print(f"  Routing: {result['receipt']['routing']}")
    print(f"  Integrity: {result['attestation']['integrity']}")
    print(f"  Settlement: {result['attestation']['settlement']}")
elif result["status"] == "invalid":
    print("VERIFICATION FAILED -- receipt may have been tampered with.")
elif result["status"] == "not_found":
    print("Receipt ID not found.")

Interpreting the Result

Status Meaning Action
verified All checks passed Safe to use in audit trail
invalid Commitment or signature mismatch Investigate -- possible tampering
not_found Receipt ID does not exist Check the receipt ID for typos
expired Past verification window Contact support for historical verification

Step 3: Verify via CLI (Local)

For independent verification without contacting SIX:

six verify receipt.json

Expected output:

Receipt: rcpt_f8c505ce3a7b4d2e9f1a...
  Commitment:  VALID
  Signature:   VALID
  Routing:     sovereign
  Attestation: intact
  Settlement:  anchored

Status: VERIFIED

Why local verification matters

API verification asks SIX to verify its own receipt. Local verification runs entirely on your machine using the published SIX public key. For audit purposes, local verification demonstrates stronger independence.

CLI Tool Access
The six CLI tool is distributed to NDA partners. It runs locally with no network dependency.

Request access →

What Each Field Proves

When verification succeeds, you have mathematical proof of the following:

Field What You Know
receipt_id This specific inference execution is uniquely identified and trackable
routing Your data was processed on the compute path you specified (sovereign, standard, confidential)
commitment No receipt fields were modified after issuance -- the cryptographic binding is intact
signature The receipt was generated by authorized SIX infrastructure, not forged
verified Server confirmed validity at issuance (verify independently for compliance)

Tamper Detection

Try modifying a receipt field and verifying again:

import copy

# Tamper with the routing field
tampered = copy.deepcopy(receipt)
tampered["routing"] = "standard"  # was "sovereign"

# Attempt verification -- this WILL fail
# The commitment was computed over the original fields
# Changing any field breaks the binding

This is the point

The entire SIX receipt system is designed so that tampering is immediately detectable. There is no way to modify a receipt field and produce a valid commitment without the signing key.


Batch Verification

For verifying multiple receipts (e.g., during an audit):

receipt_ids = [
    "rcpt_f8c505ce3a...",
    "rcpt_a1b2c3d4e5...",
    "rcpt_9f8e7d6c5b...",
]

results = []
for rid in receipt_ids:
    resp = requests.get(
        f"https://six-sov.com/v1/verify/{rid}",
        headers={"Authorization": f"Bearer {SIX_API_KEY}"}
    )
    result = resp.json()
    results.append({
        "receipt_id": rid,
        "status": result["status"],
        "verified_at": result.get("verified_at"),
    })

# Generate audit report
verified = [r for r in results if r["status"] == "verified"]
failed = [r for r in results if r["status"] != "verified"]

print(f"Verified: {len(verified)}/{len(results)}")
if failed:
    print(f"FAILED: {[r['receipt_id'] for r in failed]}")

Audit Trail Best Practices

Practice Reason
Verify receipts at time of inference and periodically Proves ongoing integrity, not just point-in-time
Store verification results in your audit system Independent record under your control
Use CLI/manual verification for audit preparation Demonstrates independence from SIX infrastructure
Log who verified and when Satisfies access control audit requirements

Next Steps