Errors
Every error response is JSON with ok: false and an error message.
Stage failures and sealed deny or halt outcomes get a 422 with the
failing stage named explicitly.
Error envelope
{
"ok": false,
"duration_ms": 12,
"error": "human-readable message",
"error_stage": "DOG"
}
Input-validation errors (HTTP 400) carry only ok and error. error_stage is populated for stage errors and for sealed deny or halt responses. It names the pipeline stage or governance gate that stopped the run:
DOG PEPG PROGRAM DTL DKEC CCV MACC AIVP_T4 HARDWARE AER TOK DSC
NREP ZKSP PHASE4 LEDGER REGISTRY DLA BUNDLE_ANCHOR PEPG_ADMISSION
PHASE4 is the proof and state binding stage (stage 6). BUNDLE_ANCHOR is the complete-record anchor written after the pipeline finishes. PEPG_ADMISSION is the attestation-gap check that runs before the pipeline.
Governance gates:
PEPG, Pre-Execution Policy Gate denied the request (stage 1.5, after DOG). Response includes a sealeddeny_receiptand thepartial_manifest. No kernel executed.CCV, Continuous Constraint Verification found a per-run budget breach at the post-DKEC boundary. The consumption it counts is caller-declared (request_substance.cost.total_tokens; none reported counts as zero). Response includes a sealedccv_halt_receiptand thepartial_manifest.MACC, Multi-Agent Coordination Constraint found the budget bucket's cumulative caller-declared consumption over its limit (stage 3.6, after DKEC and CCV, before AER). From run 247 on, the bucket is the authenticated API key. Response includes a sealedmacc_halt_receiptand thepartial_manifest. The kernels had already executed; the AER and every later stage did not run.AIVP_T4, Tier-4 governance refused to release the AI output (stage 3.7). Response includes a sealedaivp_t4_halt_receiptand thepartial_manifest.PEPG_ADMISSION, the active policy requires attested fields the caller did not declare. Response includes a sealedattestation_gap_receipt. The pipeline did not run. The hosted API's built-in policy requires no attested fields, so the hosted API does not currently return this.
Status codes
| Code | When | Caller action |
|---|---|---|
| 200 | Run completed (ok: true) | Read the manifest |
| 400 | Malformed JSON, missing required field, bad hex | Fix the request |
| 401 | Missing or invalid X-Verdifax-Key (once any key has been created, revoked or not) | Provide a valid key |
| 404 | Run id not found, or not visible to the caller's key | Confirm the id and the key |
| 422 | Sealed deny or halt (PEPG, CCV, MACC, AIVP_T4, PEPG_ADMISSION), or a stage error | Read error_stage; fetch the sealed receipt if one is included |
| 429 | Rate limit exceeded (per-key) | Retry after the Retry-After header |
| 500 | Unhandled internal error | Report to the operator with the error message, the endpoint, the time of the call and the run_id if one was returned |
Stage errors vs. sealed halt outcomes
Both return HTTP 422 with ok: false. The difference is whether a sealed receipt exists.
Sealed deny and halt outcomes (policy or budget decision, sealed artifact):
PEPG, The policy denied the request. On the hosted API, whose only rule admits every request, this is a Malicious Code Defense signature match (decision_reason_codeMCD_SIGNATURE_MATCH).deny_receiptincluded.CCV, Per-run budget breached at the post-DKEC boundary.ccv_halt_receiptincluded, partial manifest sealed.MACC, Cumulative budget exceeded.macc_halt_receiptincluded, partial manifest sealed.AIVP_T4, Tier-4 governance refused release.aivp_t4_halt_receiptincluded, partial manifest sealed.PEPG_ADMISSION, Required attested fields missing.attestation_gap_receiptincluded.
Stage errors (pipeline failure, unsealed):
When a pipeline stage fails (e.g., DOG envelope parsing fails, DKEC kernel crashes), the orchestrator persists the run with status stage_error and returns HTTP 422 with error_stage set. The run is still visible in /runs and /runs/{id} for forensic review, failures are auditable, not silent.
{
"ok": false,
"duration_ms": 3,
"error": "orchestrator: stage DKEC failed: ...",
"error_stage": "DKEC"
}
No sealed artifact exists for stage_error runs. The run record itself is the only evidence, and it is not independently verifiable.
Input validation happens before any of this. A request with a bad field (for example, a program_id that is not 64-char hex) gets HTTP 400 and no run is persisted:
{
"ok": false,
"error": "program_id must be 64-char hex, got 7 chars"
}
