Verification
Verification takes an asset (by attestation_id, image bytes, or video + manifest) and returns a Verification Result — the risk score, the factors that produced it, the chain of custody, and device info.
The result
{
"attestation_id": "<uuid>",
"claim_id": "<string | null>",
"status": "verified | partial | failed",
"risk_score": 0,
"risk_factors": [ { "factor": "no_manifest", "points": 60, "description": "…" } ],
"chain": [ { "event_type": "capture", "timestamp": "…", "actor": "device:…", "summary": "…" } ],
"device_info": { "device_id": "…", "enrolled": true, "cert_valid": true, "cert_expires": "…" },
"capture_type": "image",
"liveness_checked": false,
"synthetic_media_score": null,
"synthetic_media_factors": null,
"verified_at": "<RFC3339>",
"sensor_hash": "<SHA-256 hex | null>"
}
sensor_hash echoes the signed bundle's hash: for an image, the SHA-256 of the raw bytes; for a video, the chunk-chain root. Use it to prove a file you hold is this asset before acting on it. The dashboard's Screen this asset does exactly that: it hashes the original you choose in the browser and only sends it to screening when the hash matches. It is null when there is no signed bundle (no_manifest).
Statuses
status is derived from risk_score (see risk scoring):
| Score | Status | Meaning |
| --- | --- | --- |
| 0–30 | verified | Auto-approve |
| 31–60 | partial | Adjuster review |
| 61–80 | partial | Enhanced review |
| 81–100 | failed | SIU escalation |
Flow
- Locate the manifest — extract the XMP bundle (image) or take the sidecar manifest (video). None found →
no_manifest. - Recompute the hash — image bytes →
sensor_hash; video bytes → chunk chain. - Verify the signature against
device_cert, and the cert chain against the root CA. - Check the registry — is the device enrolled? revoked?
- Score — apply the additive rules, cap at 100, derive the status.
- Screen if needed — an image with
no_manifestand?screen=true(sandbox default) also gets a synthetic-media score, kept as a separate field.
Two independent signals
risk_score answers "can we prove this is authentic?" synthetic_media_score answers "does an external detector think this looks AI-generated?" They are never merged. High confidence on the first makes the second irrelevant; the second only matters when the first can't vouch.