Receipts
Use a receipt to prove which governed result, gate run, eval, or monitoring event the platform recorded. Verification uses a public endpoint and does not send your API key.
Status: Beta Companion docs: Public verification API · Testing and CI · Observability Source of truth: Public verification API and the SDK
ReceiptHandle.
Know the five receipt families
| Prefix | Family | Created for |
|---|---|---|
dlir_ | Govern | Governance decisions |
gr_ | Gate | Gate runs and deployment checks |
eh_ | Eval | Eval harness runs |
evow_ | Winner | The selected eval model or configuration |
ema_ | Monitor | Continuous-assurance monitoring events |
The prefix tells you which workflow minted the receipt. It does not replace verification.
Read a governance receipt
from trinitite import Trinitite
tr = Trinitite(env="prod")
resp = tr.client("openai", credential="cred_openai_prod").chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Summarize order #4821."}],
)
result = tr.result(resp)
if result.receipt is not None:
print(result.receipt["id"])
print(result.receipt.get("verify_url"))
The result receipt block is dict-like. Its stable fields are id and verify_url.
Verify without authentication
if result.receipt is None:
raise RuntimeError("This result has no receipt")
verification = result.receipt.verify()
if not verification.ok:
raise RuntimeError(verification.body)
assert verification.body["verified"] is True
print(verification.body["receipt_id"])
result.receipt.verify() calls GET /v1/public/receipts/{id}/verify with no bearer token.
Handle a missing receipt
Receipt minting can produce no id for a result. Check the handle before verification.
receipt = result.receipt
if receipt is None or not receipt.get("id"):
record_unverified_result(result.id)
else:
verified = receipt.verify().body.get("verified", False)
Calling verify() without an id raises ValueError. A receipt handle created without a client raises RuntimeError because it cannot make the verification request.
Read gate receipts
Gate runs use typed GateReceiptHandle objects.
gate = tr.gate.get("gate_refund_release")
for receipt in gate.runs(limit=5):
print(receipt.gate_run_id)
print(receipt.passed)
print(receipt.failures)
if receipt.run_id:
scenario_results = receipt.replay()
print(scenario_results.body)
A gate receipt id uses gr_. The linked run_id points to per-scenario results. receipt.replay() raises ValueError if no linked run exists yet.
Keep receipt ids with application records
audit_record = {
"order_id": "4821",
"decision_id": result.id,
"receipt_id": (
result.receipt.get("id")
if result.receipt is not None
else None
),
}
Store the opaque id and verification URL. Fetch current verification status when you need to validate the artifact.
Next steps
- Traces and graph: walk the decision lineage around a receipt.
- Observability: replay the governed call and audit the log chain.
- Testing and CI: require a
gr_gate receipt at deployment.