Reason codes
A reason code explains a negative outcome inside a 200 response: an intent verify that returns valid: false, a risk factor on a verification, or a traced inference whose completion was withheld. The request itself succeeded, so these are not errors. Each code is listed once, with every place it appears.
Your own policy rules can set their own reason strings. Those come back as written and are not listed here.
| Code | Appears in | Meaning |
|---|---|---|
action_hash_mismatch | Intent verify | The action_description sent to verify isn't the one the human authorized. Verify with the exact description passed to authorize. |
agent_suspended | Intent verify | The token's registered agent is suspended. Resume the agent with POST /v1/agents/:id/unsuspend after review. |
agent_unsuspended | Decision ledger | Clearing a lock also resumed the agent it had suspended. No action. |
ai_generated_likely | Screening factor | The external detector's genai model scored the media as likely AI-generated (advisory, never part of risk_score). Review the asset; detector accuracy drops after recompression. |
approval_denied | Intent verify | The human denied the step-up approval. Don't execute the action. |
approval_expired | Intent verify | The step-up approval expired before anyone decided it. Authorize again to open a new approval. |
approval_pending | Intent verify | A step-up approval is waiting for a human; the response carries approval_id. Poll verify or wait for the approval.resolved webhook. See step-up approval. |
approval_required | Decision ledger | A policy rule requires human approval (the engine's internal outcome before an approval request exists). No action; verify turns it into approval_pending. |
biometric_absent | Risk factor | No biometric gated the capture (+10). Confirm with Face ID, Touch ID or a passkey at capture. |
biometric_required | Intent verify | The default policy's biometric rule matched (context.require_biometric) and the token isn't biometric-bound. Authorize with a verified passkey assertion. |
c2pa_absent | C2PA factor | No C2PA manifest is present (advisory). No action. |
c2pa_invalid | C2PA factor | A C2PA manifest is present but malformed or its signature fails (advisory). Treat the embedded manifest as untrusted. |
c2pa_present_valid | C2PA factor | A C2PA manifest is present, well-formed and its signature verifies (advisory). No action. |
canary_reading_mismatch | Intent verify | The trace id's stored reading hash differs from the one bound into the token. Authorize again with the current trace_id. |
canary_tripped | Intent verify, Finish reason | A canary family reached its threshold: on verify a canary policy rule denied the action; on traced inference the completion was withheld (finish_reason: "canary_tripped"). Review the readings in canary_readings and the trace. See kill switch. |
canary_unavailable | Intent verify | A strict canary condition had no reading to evaluate; the response names canary_set. Pass a trace_id or inference_input, or mark the condition best_effort. See canary policies. |
carrier_policy_attestation_missing | Risk factor | Your carrier risk policy requires an attested capture for this claim and it's absent (advisory). Ask the policyholder to capture through the SDK. |
carrier_policy_biometric_missing | Risk factor | Your carrier risk policy requires a biometric for this claim and it's absent (advisory). Ask the policyholder to re-capture with a biometric. |
carrier_policy_gps_missing | Risk factor | Your carrier risk policy requires GPS for this claim and it's absent (advisory). Ask the policyholder to re-capture with location on. |
cert_unknown_ca | Risk factor | The device certificate isn't signed by a known root CA (+40). Enroll devices through the Provenance PKI. |
context_hash_mismatch | Intent verify | The context_evidence re-supplied at verify doesn't hash to the token's context_hash. Re-supply the exact context evidence sent to authorize, or omit it. |
controlled_substance_cosign_required | Clinician orders | The order needs a second clinician's co-signature before it authorizes. Have a second clinician approve the order. |
cross_claim_link | Risk factor | The asset shares a device, location or cloned certificate with another claim (advisory). Review the linked claims at GET /v1/claims/:id/links. |
deepfake_likely | Screening factor | The external detector's deepfake model scored the media as a likely deepfake (advisory). Review the asset. |
device_not_enrolled | Risk factor | The signing device isn't in the registry (+20). Enroll the device with POST /v1/admin/devices. |
device_revoked | Risk factor | The signing device is revoked (+80). Re-enroll a trusted device for new captures. |
exif_editor_trace | Risk factor | The EXIF Software tag names an image editor (advisory). Review the asset for post-processing. |
exif_missing | Risk factor | A fresh capture has no EXIF metadata (advisory). Review whether the image was re-encoded. |
exif_timestamp_mismatch | Risk factor | EXIF DateTimeOriginal differs from the attestation timestamp beyond tolerance (advisory). Review the capture time. |
frame_hash_mismatch | Risk factor | The recomputed chunk hash chain doesn't match the manifest (+50). Submit the original recorded bytes. |
geofence_mismatch | Risk factor | The attestation GPS is far from the claim's stated loss location (advisory). Review the stated loss location. |
gps_absent | Risk factor | The bundle has no GPS fix (+30). Allow location access at capture. |
hardware_backing_absent | Risk factor | The server-verified hardware tier is software, or the attestation evidence is missing (+40). Capture on a device with a Secure Enclave, StrongBox or TEE. |
hardware_required_above_500 | Intent verify | The default policy requires a hardware-attested device for context.transaction_amount above 500. Authorize from a hardware-backed device, or set your own policy. |
insufficient_evidence | Case reason | The adjuster couldn't decide on the evidence provided. Request more evidence from the policyholder. |
invalid_token | Intent verify | The intent token is malformed or its signature doesn't verify against the JWKS. Pass the exact intent_token returned by POST /v1/intent/authorize. |
length | Finish reason | The completion hit max_tokens. Raise max_tokens or shorten the prompt. |
liveness_check_failed | Risk factor | The live session's timing and continuity heuristics failed (+40); this is not biometric liveness. Record live with a steady connection. |
mandate_budget_exceeded | Intent verify | The action would exceed the mandate's remaining budget. Ask the human to grant more budget. |
mandate_constraint_violated | Intent verify | The action breaks a static mandate constraint (amount, action type or counterparty); mandate_detail names it. Keep the action inside the mandate's constraints, or ask for a broader mandate. |
mandate_expired | Intent verify | The delegation mandate is past its expiry. Ask the human to grant a new mandate. |
mandate_heartbeat_lapsed | Intent verify | The mandate missed its heartbeat check-in and is suspended. Have the human check in with POST /v1/mandates/:id/heartbeat within the reactivation window. |
mandate_revoked | Intent verify | The delegation mandate the token was authorized under is revoked. Ask the human to grant a new mandate. |
no_manifest | Risk factor | The asset carried no signed manifest (+60). Capture through the Provenance SDK, or screen legacy media with POST /v1/media/screen. |
order_declined | Clinician orders | The clinician declined the order. Don't place the order. |
other | Case reason | Another reason, described in the required note. Read the case note. |
payload_hash_mismatch | Intent verify, Clinician orders | The action_payload about to run isn't byte-identical (canonical JSON) to the one the human authorized. Execute the exact authorized payload, or authorize the changed one. |
policy_biometric_required | Intent verify | A policy rule requires a biometric-bound token and this one isn't. Authorize with a verified passkey assertion. |
policy_denied | Intent verify | A policy rule with require.deny matched; the response names matched_rule_id. Change the action or the account policy. See policies. |
policy_hardware_required | Intent verify | A policy rule requires a hardware-attested device and this one isn't. Authorize from an enrolled hardware-backed device. |
policy_tier_required | Intent verify | A policy rule requires a higher hardware tier than the device has. Authorize from a device at the required tier. |
policy_webhook_denied | Intent verify | Your policy webhook answered deny; webhook_reason carries its reason. Check your webhook's decision logic. |
policy_webhook_pending | Decision ledger | The engine needs a policy webhook decision that wasn't fetched yet (internal to evaluation and simulate). No action; verify resolves it. |
policy_webhook_unavailable | Intent verify | Your policy webhook timed out, errored or answered malformed JSON, and the rule fails closed. Check that the webhook answers within 3 seconds with a valid decision. |
policyholder_withdrew | Case reason | The policyholder withdrew the claim. No action. |
prescriber_excluded | Clinician orders | The prescriber matched an exclusion list (OIG LEIE or SAM.gov); this is a hard deny at any tier. Don't route orders to this prescriber. |
prescriber_tier_insufficient | Clinician orders | The prescriber's verified tier is below what the clinical order policy requires. Verify the prescriber to the required tier. See clinician ordering. |
provenance_verified | Case reason | The adjuster approved on verified provenance. No action. |
reading_too_old | Decision ledger | The kill-switch check's reading is older than max_age_s, so the answer is stale. Re-read the canaries with a fresh traced inference. |
risk_accepted | Case reason | The adjuster approved despite flagged risk. No action. |
schedule_already_executed | Intent verify | This cycle already executed once. Wait for the next cycle. |
schedule_amount_exceeded | Intent verify | The amount differs from the schedule's fixed amount or exceeds its maximum. Execute the scheduled amount. |
schedule_counterparty_mismatch | Intent verify | The action's counterparty isn't the schedule's counterparty. Execute the scheduled payment to the scheduled counterparty. |
schedule_occurrences_exhausted | Intent verify | The schedule ran all of its occurrences. Ask the human to grant a new standing schedule. |
schedule_window_missed | Intent verify | The current cycle's execution window is closed. Execute inside the next cycle's window. |
sensor_hash_mismatch | Risk factor | The image bytes don't hash to the bundle's sensor_hash (+50). Submit the original captured bytes. |
session_canary_locked | Intent verify | The agent session or agent is locked after a canary trip under block_and_lock; the response carries lock_id. Review the trace, then clear the lock with POST /v1/trace/session-locks/:lock_id/clear. See kill switch. |
session_lock_cleared | Decision ledger | A human cleared a canary session lock (ledger kind lock_clear). No action. |
session_nonce_mismatch | Risk factor | The bundle's session_nonce or chain seed isn't the server-issued nonce (+70), the signature of a replayed feed. Record live in a fresh capture session. |
shadow_webhook_unevaluated | Decision ledger | A shadow policy rule needed a webhook, and shadow evaluation never calls webhooks; the shadow result is pending. Read divergence from the other shadow decisions in the shadow report. |
signature_invalid | Risk factor, Case reason | The bundle's ECDSA signature failed (+70); as a case reason it records a denial on that ground. Treat the asset as altered; re-capture if it should be authentic. |
stop | Finish reason | The model finished its completion. No action. |
suspected_fraud | Case reason | The adjuster denied or escalated for suspected fraud. Route to SIU. |
timestamp_stale | Risk factor | The capture is more than 72 hours older than the claim submission (+25). Submit captures promptly. |
token_expired | Intent verify | The intent token is past its exp. Authorize the action again to mint a fresh token. |
token_revoked | Intent verify | The token, its agent session or its device was revoked; the response names revoked_scope. Authorize again once the revocation no longer applies. See revocation. |
video_manifest_incomplete | Risk factor | The video manifest has non-contiguous indices, a count mismatch or missing fields (+40). Submit the full chunk manifest. |