AttestationReceipt
Pydantic model returned by attest(). Wraps the full
ExecutionManifest with metadata.
Import
from verdifax import AttestationReceipt
Fields
| Field | Type | Notes |
|---|---|---|
ok | bool | Always True for receipts returned by a successful attest() |
run_id | int or None | Server-side persistent run id (Phase 3+; None if the API doesn't persist) |
duration_ms | int | Pipeline wall-clock duration |
manifest_hash | str | 64-char hex; identical to manifest.manifest_hash (exposed at top level for convenience) |
manifest | ExecutionManifest | The full sealed manifest |
received_at | datetime | UTC timestamp the SDK received the response |
Example
receipt = client.attest(...)
print(receipt.manifest_hash) # "6c1428f81519c5bb..."
print(receipt.run_id) # 42 (or None)
print(receipt.duration_ms) # 3
print(receipt.manifest.envelope_id) # "env-..."
print(receipt.received_at) # datetime in UTC
Stages
For convenience, receipt.manifest.stages() projects the sealed fields into the canonical nine-stage breakdown:
for stage in receipt.manifest.stages():
print(stage.stage_number, stage.stage_name)
for k, v in stage.artifacts.items():
print(" ", k, "=", v)
Frozen by design
The model is immutable — Pydantic v2 frozen=True. You cannot mutate a receipt after construction; create a new one. This is intentional so a receipt cannot be silently modified between attestation and audit.
Serialization
receipt.model_dump() # snake_case keys
receipt.model_dump(by_alias=True) # PascalCase keys (matches the API response)
receipt.model_dump_json() # JSON string
