Sealed artifact endpoints
Four endpoints, one per outcome state, each returning the cryptographically sealed artifact a third party needs to replay the decision without trusting Verdifax.
See Outcome states & sealed artifacts for the conceptual overview and field-level schema.
Endpoints
GET /runs/{id}/allow-token → AllowToken (PEPG admit + nine-stage pipeline)
GET /runs/{id}/deny-receipt → DenyReceipt (PEPG)
GET /runs/{id}/ccv-halt-receipt → CCVHaltReceipt (CCV)
GET /runs/{id}/macc-halt-receipt → MACCHaltReceipt (MACC)
Each endpoint returns the sealed artifact for run {id} if and only if the run resolved to the matching outcome state. Otherwise it returns 404 Not Found with a clear error explaining which state the run is in.
How to pick the right endpoint: Use the outcome_kind field from the run summary (GET /runs/{id}):
ok→/runs/{id}/allow-tokenpepg_deny→/runs/{id}/deny-receiptccv_halt→/runs/{id}/ccv-halt-receiptmacc_halt→/runs/{id}/macc-halt-receiptstage_error→ No artifact endpoint exists (run record only)
Authentication
Same as every other run endpoint, pass X-Verdifax-Key: $VERDIFAX_KEY.
The orchestrator scopes results to the API key that authored the run, so
one customer cannot retrieve another customer's artifacts.
Response shape
All four return the same envelope:
{
"ok": true,
"run_id": 42,
"<artifact_key>": { ... }
}
Where <artifact_key> is one of:
allow_tokendeny_receiptccv_halt_receiptmacc_halt_receipt
The artifact object itself is a canonical-bytes record (RFC 8785 + SHA-256)
whose fields are documented in Outcome states.
The terminal hash field is the SHA-256 of the canonical preimage and
is the value verdifax-pepg-verify recomputes.
Example, fetching a DenyReceipt
curl -H "X-Verdifax-Key: $VERDIFAX_KEY" \
https://api.verdifax.com/runs/42/deny-receipt
{
"ok": true,
"run_id": 42,
"deny_receipt": {
"envelope_id": "env-7a3c…",
"fired_rule_id": "rule_classification_exceeded",
"decision_reason_code": "CLASSIFICATION_EXCEEDED",
"policy_hash": "8f1d…",
"evaluation_hash": "b2e0…",
"mcd_finding_hash": "",
"deny_clock": "2026-04-30T17:23:48.124Z",
"evaluator_version": "pepg-0.3.0",
"version": "vfa.deny_receipt.v1",
"hash": "9e7f…"
}
}
Independent verification
The audit dashboard and PDF emit a copy-pasteable command for each run.
The same command works against any of the four endpoints, only the path
and the jq selector change:
curl -H "X-Verdifax-Key: $VERDIFAX_KEY" \
https://api.verdifax.com/runs/42/deny-receipt \
| jq .deny_receipt | verdifax-pepg-verify
The verdifax-pepg-verify CLI is open-source and MIT-licensed. It re-derives
the canonical preimage, recomputes SHA-256, and compares against the
hash field. Exit code 0 confirms the seal; non-zero indicates tampering.
When you'll see 404
{ "ok": false, "error": "run 42 is \"ok\", not \"pepg_deny\", no deny_receipt exists" }
The error message names both the actual outcome state of the run and the
state required for the requested artifact. The dashboard handles this
automatically by inspecting outcome_kind on the run summary before
choosing which endpoint to call.
Outcome discriminator on run summaries
Every entry in GET /runs and GET /runs/search carries an outcome_kind
field with one of: ok, pepg_deny, ccv_halt, macc_halt,
stage_error. Use it to branch on which artifact to fetch without
parsing the manifest.
