Skip to content

Media Authenticity

Two questions can be answered about a media file without a model's opinion: does its cryptographic provenance hold, and does its own metadata contradict what somebody said about it. Both are answered here. Both are deterministic — an auditor with the same file reaches the same result.

A third question — was this generated? — is answered by a model, and is handled differently on purpose. See Advisory signals.

The response has two sections, and they never merge

POST /scan/media returns deterministic and advisory as separate lists.

Section What is in it Can it raise risk on its own?
deterministic Facts with known ground truth — a signature verifies or it does not; a container names an encoder or it does not Yes
advisory A model's opinion, as a three-value band plus what that model was never trained on No

They are different kinds of claim. A single findings list would invite a reader to act on the weaker one as though it were the stronger, so the API gives them no shared shape to be confused in.

risk_score is 0.0 by construction unless a deterministic hard positive fired. A model that cannot generalise to generators it has not seen must not be able to block traffic by itself.

No accuracy figure appears anywhere in the response. There is no field that could carry one — asserted structurally, not by convention.

Content Credentials (C2PA)

Where a file carries a C2PA manifest, the manifest is verified against the bytes and the result is exactly one of five states.

State Meaning Hard positive
no_manifest The file carries no Content Credentials No
manifest_unreadable A manifest is present and could not be parsed No — and not clean either
manifest_valid_but_signer_unknown Signature intact, signer not on the deployment's trust list No
manifest_verified_and_trusted Signature intact, signer trusted No
hard_binding_mismatch The manifest does not match the file it is attached to Yes

Why the last one is the only hard positive

hard_binding_mismatch is cryptography, not interpretation: the bytes changed after signing, or the manifest was lifted from a different file. It is the one result in the entire media layer that is not a probability.

Why the middle states are kept apart

The reference C2PA library reports a file signed by an attacker's own certificate authority as "Valid". A product that rendered that as verified would certify anything carrying any signature. manifest_valid_but_signer_unknown is the state most implementations get wrong, and on a default trust configuration it is what almost every real file produces.

Why a verified manifest is not a tick

Where a manifest verifies, the platform prints the origin the file declares verbatim. The most common verified result in 2026 is a valid, trusted signature stating that a model generated the content. A green check mark on that inverts its meaning.

Why manifest_unreadable is its own state

"We could not check this" and "there was nothing to check" are different answers and only one of them is reassuring. Folding the first into no_manifest would turn an analyzer failure into a clean result.

Absence is not evidence

Most files in circulation carry no Content Credentials at all. Platforms strip manifests on upload and any re-encode breaks the binding, so no_manifest is the ordinary state of an ordinary file.

Provenance claim consistency

Somebody says "this is the original, straight off my phone." The container says FFmpeg wrote it. Cameras do not write FFmpeg.

Pass a claim form field to turn this on. The vocabulary is closed:

Claim Contradicted by
camera_original A container naming a re-encoder or an editing suite as its writer
unedited The same, restricted to editing suites

A claim outside that vocabulary returns HTTP 400. Answering "nothing inconsistent found" to a question nobody asked would read as endorsement of it, so an uncheckable claim is refused rather than answered.

The three outcomes

Outcome Meaning
contradicted The file's own metadata disagrees with the claim
no_contradiction_found We looked and found no disagreement
not_checkable The file carries no writer metadata to compare against

There is no "claim verified" outcome and there will not be one. Three independent reasons, any one of which is sufficient:

  • Metadata can be stripped. Every messaging app and social platform does it on upload, so its absence is the normal state of an ordinary file.
  • Metadata can be forged. It is a string in a container.
  • A deepfake played on a monitor and filmed with a real camera produces a genuine camera original, with real sensor noise and real capture metadata. It would pass this check, and it should — the check is about the file's history, not the truth of what it depicts.

no_contradiction_found is the strongest available answer and it is deliberately not a pass.

A contradiction is not an accusation

A broken C2PA binding is cryptography. A contradicted claim means a person described a file inaccurately, which is far more often loose language than an attack — trimming a video re-encodes it, and so does sending it through anything. The finding states a fact about the file's history and attributes no intent to anyone, and it is not a hard positive.

Advisory signals

A synthetic-speech model is in build. When it ships it will report a three-value band beside a statement of what it was not trained on — never a verdict, never a number, and never able to block on its own.

Video synthesis classification is planned and not built, and it carries a harder constraint than audio does. Published detectors of that kind transfer poorly to generators they were not trained on, so on a real corpus the most likely output is a false positive against genuine footage.

That constraint shapes the design rather than sitting beside it as a caveat. The signal is built to be survivable when it is wrong: it never names, identifies or describes a person, it is advisory only, and it has no path to a blocking decision. A finding says a file carries synthesis-like artifacts. It never says a person is not who they appear to be.

No accuracy figure will accompany any advisory signal at any point.

Why we are training rather than licensing

Every published detector audited fails its licence chain at some layer — most commonly training data restricted to non-commercial research, which no backbone swap can cure. Ours is a classification head over a permissively licensed backbone, trained on data we hold commercial rights to end to end. See ADR-0003.

The control that does not depend on detection

Media analysis is not how wire fraud is stopped. See Compliance & Attestation for out-of-band payment verification, which works whether or not the voice on the call was synthetic.

Validation checklist

  • a signed fixture returns manifest_verified_and_trusted; the same file with one byte altered returns hard_binding_mismatch
  • an unsigned fixture returns no_manifest and not an empty result
  • claim=camera_original against an FFmpeg-written file returns contradicted
  • claim=definitely_real returns HTTP 400
  • a scan with no claim field emits zero claim findings
  • a PDF posted here returns analyzed: false with a routing reason, not a clean result

Fixtures with expected verdicts live in scripts/detection-eval/media-corpus/.