Skip to content

POST /v1/verify

Verify content against a stored provenance record. No authentication required. Always free.


POST /v1/verify
Content-Type: multipart/form-data
FieldRequiredDescription
contentYesContent to verify (image, audio, text, or video)
tokenNoctv_… token. If omitted, extracted automatically
formatNo"image", "audio", "text", or "video". Auto-detected from magic bytes if omitted.
  1. Token provided explicitly → fast path, skip extraction
  2. Format-native metadata container (XMP for images/PDF, ID3v2/VORBIS_COMMENT/CTV chunk for audio, HTML meta for HTML, cerv atom / Certivu trailer for video) → instant
  3. Resilient watermark (DCT spread-spectrum for images, DCT frame for WAV 16/24-bit, ZWC steganography for plain text and HTML body) → slower, survives transformations
  4. Perceptual hash (pHash) → fuzzy lookup against records with stored pHash, Hamming distance ≤ 8 (images and video — video uses first I-frame via ffmpeg)
  5. Acoustic fingerprint → landmark-pair FFT fingerprint match against audio records (WAV PCM only; activates when metadata tags have been stripped)
  6. Nothing found → no_provenance_found

{
"authentic": true,
"tampered": false,
"confidence": "high",
"token_source": "xmp",
"format": "image",
"signals": {
"watermark_found": true,
"record_found": true,
"signature_valid": true,
"phash_match": false,
"fingerprint_match": false,
"neural_watermark_found": false
},
"provenance": {
"org": "acme-ai",
"model": "stable-diffusion-xl",
"signed_at": "2026-03-29T00:00:00Z"
},
"c2pa": {
"found": true,
"validation_status": "valid",
"assertions": ["c2pa.actions", "c2pa.hash.data"]
}
}
ValueMeaning
"provided"Token was supplied explicitly in the request
"xmp"Token extracted from format-native metadata (XMP / ID3v2 / VORBIS_COMMENT / CTV chunk / HTML meta / PDF /Metadata)
"watermark"Token resolved via resilient watermark (DCT for images/WAV, ZWC for plain text/HTML body)
"phash"Record found via perceptual hash similarity (images and video)
"fingerprint"Record found via acoustic fingerprint match (WAV PCM only)
"neural_watermark"Record found via neural watermark (TrustMark image / WavMark audio / keyframe video) — survives social round-trips and re-encodes
nullNo provenance found
FieldTypeDescription
watermark_foundbooleanResilient watermark was successfully extracted
record_foundbooleanA matching provenance record exists in the database
signature_validbooleanML-DSA signature verified against generator’s public key
phash_matchbooleanRecord was located via perceptual hash similarity (Hamming ≤ 8, images and video)
fingerprint_matchbooleanRecord was located via acoustic fingerprint match (WAV PCM only)
neural_watermark_foundbooleanA neural watermark (TrustMark image / WavMark audio / keyframe video) was decoded — survives recompression, resize, and re-encode
ConfidenceSignalsMeaning
high(Watermark or neural watermark) ✓ + Record ✓ + Signature ✓Full chain intact, incl. social/re-encode survival
mediumRecord ✓ + Signature ✓, no watermarkRe-uploaded without watermark, still verifiable
lowPartial signalsSomething is off
noneNothing foundNot signed by Certivu — no claim either way

Present when the uploaded content contains a C2PA manifest. null or absent when no manifest is detected.

FieldTypeDescription
foundbooleanA C2PA manifest was detected
validation_statusstring"valid" or "invalid" based on C2PA manifest assertions
assertionsstring[]Labels of the assertions present in the manifest
manifest_countnumberNumber of manifests in the asset’s C2PA store
signature_issuerstringIssuer from the active manifest’s signature certificate
is_certivubooleanTrue when the active manifest was produced by Certivu

A reason field is included:

ReasonMeaning
no_provenance_foundNo token, XMP, watermark, pHash, or fingerprint match detected
record_not_foundToken decoded but record missing from DB
content_tamperedContent hash does not match stored hash
signature_invalidML-DSA signature verification failed
invalid_tokenToken could not be decoded
phash_false_positiveRecord found via pHash but content hash doesn’t match (perceptually similar but different file)

POST /v1/verify/batch
Content-Type: application/json

Up to 50 items per request.

{
"items": [
{ "content": "<base64 image>", "token": "ctv_..." },
{ "content": "<base64 image>" }
]
}

Returns an array of VerificationResult objects in the same order.


GET /v1/verify/status/:token

Lightweight status check by ctv_ token — no content upload required. Returns generator and signing metadata for a token without running a full verification. The response is CDN-cacheable (Cache-Control: public, max-age=3600), making it efficient for badge endpoints, link previews, or pre-flight checks before embedding a token in content.

Path parameter

ParameterDescription
:tokenA ctv_ token returned by the sign endpoint

Response 200

{
"record_id": "rec-uuid",
"generator_status": "active",
"model": "stable-diffusion-xl",
"signed_at": "2026-03-29T00:00:00Z",
"org_id": "org_xyz789"
}
FieldTypeDescription
record_idstringProvenance record ID
generator_statusstring"active" or "revoked" — if revoked, content provenance cannot be trusted
modelstringAI model that produced the content
signed_atstringISO 8601 timestamp of when the record was signed
org_idstringOrg that created the record

Errors

StatusReason
400Token missing or malformed
404No record found for this token

  • Verification never requires authentication
  • Verification is not rate-limited per plan — IP rate limiting only (abuse prevention)
  • Absence of provenance data does not imply human origin
  • The pHash lookup scans the most recent records with a stored phash. For high-volume deployments, Atlas Vector Search is recommended to scale this path beyond the default scan window
  • C2PA signals are read-only — Certivu reports what the manifest says, not whether the C2PA signer is trusted