Skip to content

Verification States Reference

Verification States Reference

This page is the normative reference for the status field returned by POST /v1/verify. It is a closed enum. The enum is enforced by the Pydantic model in apps/api and the Zod schema in packages/shared-types.

Adding a new state code requires an RFC in docs/rfcs/. The strings real, fake, authentic, genuine, verified-truth, and confirmed-deepfake are permanently excluded.

Complete state table

CodeConfidenceSignals requiredUser labelCategory
verified_manifest_and_watermark_matchHigh (0.95+)C2PA valid + watermark decoded + watermark_id matches”Provenance verified — manifest and watermark agree”Positive
verified_manifest_intactHigh (0.92+)C2PA valid; watermark not required by recipe”Provenance verified — manifest intact”Positive
anchor_confirmedSupplementalManifest digest in confirmed anchor batch”Anchored — manifest found in timestamped batch”Supplemental
watermark_onlyMedium (0.75-0.90)Watermark decoded, maps to manifest; no C2PA manifest in file”Watermark found — manifest not present in file”Partial
fingerprint_match_onlyMedium (0.70-0.85)pHash match; no manifest or watermark in submitted file”Perceptual match found”Partial
multiple_candidatesLowMultiple soft-binding matches with overlapping confidence”Multiple matches found — review required”Ambiguous
partial_provenanceLow-mediumSome signals pass; at least one required signal fails”Partial provenance — some signals missing”Partial
no_provenanceNoneNo manifest, watermark, or fingerprint match”No provenance record found”Negative
manifest_tamperedNone (hard failure)Manifest present; claim digest does not match asset”Manifest tampered”Hard failure
revokedNone (hard failure)OCSP response: revoked”Signing certificate revoked”Hard failure
expiredNone (hard failure)Signing certificate expired at sign time”Signing certificate expired”Hard failure
trust_list_missNone (hard failure)Signer not on trust list”Signer not trusted”Hard failure
ocsp_unavailableWarningOCSP responder unreachable”OCSP check unavailable”Warning
ingredient_chain_brokenNone (hard failure)Recipe requires full chain; parent manifest missing”Ingredient chain broken”Hard failure
anchor_not_foundSupplemental (informational)Manifest digest not found in any anchor batch”Not yet anchored”Informational
errorNoneInternal verification error”Verification error”Error

Signal weights

The confidence score is a weighted sum of independent signals:

SignalDefault weightNotes
c2pa_signature_valid0.35Highest weight: cryptographic foundation
signer_trusted0.25Trust list match
ocsp_status: good0.15Certificate revocation check
timestamp_valid0.10RFC 3161 timestamp within certificate validity window
watermark_present0.10Watermark decoded successfully
watermark_payload_valid0.05Watermark ID maps to manifest record

Anchor and fingerprint signals are supplemental — they add context but do not affect the primary confidence score.

Transition rules

┌──────────────────────────────────────────────────┐
│ Manifest present? │
└──────────────────────────────────────────────────┘
│ Yes │ No
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────────┐
│ C2PA sig valid? │ │ Watermark present? │
└─────────────────────────┘ └─────────────────────────────┘
│ Yes │ No │ Yes │ No
▼ ▼ ▼ ▼
┌──────────────────┐ ┌──────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Signer trusted? │ │ tampered │ │ watermark_only │ │ pHash match? │
└──────────────────┘ └──────────┘ └─────────────────┘ └──────────────────┘
│ Yes │ No │ Yes │ No
▼ ▼ ▼ ▼
OCSP? trust_ │ Watermark also fingerprint_ no_
list_miss │ matches? match_only provenance
│ ▼
├── revoked verified_manifest_
├── expired and_watermark_match
└── good ───► verified_manifest_
intact (no watermark)
OR
verified_manifest_
and_watermark_match

SDK constants

Python

from verbitas.types import VerificationStatus
VerificationStatus.VERIFIED_MANIFEST_AND_WATERMARK_MATCH
VerificationStatus.VERIFIED_MANIFEST_INTACT
VerificationStatus.NO_PROVENANCE
VerificationStatus.MANIFEST_TAMPERED
# ... all 16 values

TypeScript

import type { VerificationStatus } from "@verbitas/sdk";
// Type-safe pattern matching:
const status: VerificationStatus = result.status;
const POSITIVE_STATES: VerificationStatus[] = [
"verified_manifest_and_watermark_match",
"verified_manifest_intact",
];
const HARD_FAILURE_STATES: VerificationStatus[] = [
"manifest_tampered",
"revoked",
"expired",
"trust_list_miss",
"ingredient_chain_broken",
];

Go

import verbitas "github.com/verbitas/sdk-go"
switch result.Status {
case verbitas.StatusVerifiedManifestAndWatermarkMatch:
// highest confidence
case verbitas.StatusManifestTampered:
// hard failure
case verbitas.StatusNoProvenance:
// no record
}

What states prove and do not prove

All states are accompanied by proves and does_not_prove arrays in the response. These arrays are mandatory — no verification result is emitted without both.

See Concepts: Verification States for examples of proves and does_not_prove content.