Vai al contenuto

Verifica un file

POST https://api.kennmarq.com/v1/verify

GET https://api.kennmarq.com/v1/credentials/{watermark_id}

GET https://api.kennmarq.com/v1/verify/key

Cosa dicono il manifest C2PA e le filigrane invisibili di un’immagine, di un brano o di una clip, nostri o di chiunque altro; su richiesta, come risultato firmato da noi. Gratis, senza chiave. La pagina del verificatore fa lo stesso per le immagini nel tuo browser, senza caricare nulla.

POST /v1/verify

Invia l’immagine come multipart/form-data in file (PNG, JPEG o WebP; la richiesta è al massimo di 4 MB). Aggiungi signed=true per un risultato firmato. I nostri server a Zurigo leggono il file in memoria e non conservano nulla. Un’immagine più grande, fino a 25 MB, passa da un upload indicato in upload, che richiede la chiave che lo ha creato; oppure verificala sulla pagina del verificatore, nel tuo browser, con qualsiasi dimensione fino a 25 MB. Brani (MP3, WAV, M4A) e clip (MP4) vengono letti sui nostri server allo stesso modo, fino a 25 MB, con una chiave (una qualsiasi delle tue, gratis; non conta nulla): vedi brani e clip.

curl
curl https://api.kennmarq.com/v1/verify -F file=@picture.jpg -F signed=true
200 application/json
{
  "object": "check",
  "checked_at": "2026-11-12T10:00:00Z",
  "checker": { "name": "Kennmarq.com", "version": "0.4.0" },
  "file": { "type": "image/jpeg", "bytes": 482113, "width": 1024, "height": 768, "sha256": "…" },
  "c2pa": {
    "state": "Trusted",
    "manifest": "urn:c2pa:3fa85f64-…",
    "signer": { "common_name": "Kennmarq.com", "issuer": "Neuramare", "ours": true, "environment": "live" },
    "signed_at": "2026-11-12T09:58:31+00:00",
    "time_stamp": { "validated": true, "trusted": true },
    "claim_generator": "Kennmarq.com 0.4.0",
    "ai": { "digital_source_type": "http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia", "generated": true },
    "soft_binding": { "alg": "com.adobe.trustmark.Q", "value": "1*0101…" },
    "failures": []
  },
  "watermark": { "found": true, "alg": "com.adobe.trustmark.Q", "schema": "BCH_5", "id": "1d455a804e9802a6", "matches_manifest": true },
  "durable_credential": {
    "watermark_id": "1d455a804e9802a6",
    "manifest": "urn:c2pa:3fa85f64-…",
    "environment": "live",
    "asset_sha256": "…",
    "same_file": true,
    "log_index": 1834001,
    "url": "https://api.kennmarq.com/v1/credentials/1d455a804e9802a6"
  },
  "log": { "leaf_index": 1834001, "status": "included", "proof_url": "https://api.kennmarq.com/v1/log/proof/1834001" },
  "signed": { "jws": "eyJhbGciOiJFUzI1NiIs…", "key_id": "…", "log_index": 1834530 }
}
  • c2pa è null quando il file non contiene un manifest. state è Trusted quando la firma risale ai nostri certificati radice (ours), Valid per un altro firmatario la cui firma risulta corretta, e Invalid quando il file è cambiato dopo la firma; failures elenca i codici.
  • watermark.id è valorizzato per le filigrane nel nostro schema (BCH_5); le altre filigrane TrustMark risultano trovate, con il loro schema, quando il centro dell’immagine restituisce esattamente la stessa lettura, così un’immagine senza marcatura non ne mostra una per caso. La nostra si legge anche in un’immagine salvata ruotata di lato o capovolta.
  • durable_credential: ciò a cui rimanda la filigrana nei nostri archivi, quando il file l’abbiamo firmato noi. Quando una piattaforma rimuove i metadati, è così che si ritrova la credenziale di provenienza; same_file indica se è proprio il file che abbiamo firmato, ed è null per un file marcato in modalità locale, che non ci è mai arrivato.
  • log: la voce del manifest nel nostro registro di trasparenza.
  • Brani e clip: file ha seconds (e, per una clip, le sue dimensioni); watermarks contiene la lettura Video Seal della clip (id, letto da 64 fotogrammi, e agreement, la quota dei suoi 256 bit che concordano) e quella AudioSeal (detected, la quota del suono che risulta marcata, e bits su 16); c2pa aggiunge claims, le filigrane che il manifest dichiara presenti nel file, e il watermark_record di una clip. watermark è allora il Video Seal della clip, che rimanda alla sua credenziale di provenienza durevole come quello di un’immagine, oppure l’AudioSeal del brano, che dice che il file è stato marcato da noi ma non contiene alcun ID.

Risultati firmati

Con signed=true, signed.jws è un JWS (RFC 7515, compatto) firmato con ES256 dalla chiave del nostro verificatore: il suo payload è il risultato qui sopra (il file, il suo manifest e la sua filigrana, l’ora), più iss, iat e un jti univoco; il kid del suo header indica la chiave. Prima di essere restituito entra nel nostro registro di trasparenza come voce checker.result (lo SHA-256 del JWS, quello del file e l’ID della chiave), all’indice riportato in X-Log-Index. Qualsiasi libreria JWT lo verifica con la chiave di GET /v1/verify/key.

Node.js (jose)
import { decodeProtectedHeader, importSPKI, jwtVerify } from "jose";

const { jws } = result.signed;
const { kid } = decodeProtectedHeader(jws);
const key = await (await fetch(`https://api.kennmarq.com/v1/verify/key?key_id=${kid}`)).json();
const { payload } = await jwtVerify(jws, await importSPKI(key.public_key, "ES256"), { issuer: "Kennmarq.com" });
// payload.file.sha256 is the SHA-256 of the file that was checked; compare it with yours.
console.log(payload.file.sha256, payload.checked_at);

GET /v1/credentials/{watermark_id}

Il manifest store C2PA a cui rimanda una filigrana, conservato dal momento in cui abbiamo firmato il file: in JSON (lo store in base64 in manifest_store), oppure con ?format=c2pa come file .c2pa leggibile da qualsiasi strumento C2PA. Chiunque sappia leggere la filigrana può scaricarlo, quindi chiunque abbia l’immagine.

curl
curl "https://api.kennmarq.com/v1/credentials/1d455a804e9802a6?format=c2pa" -o credential.c2pa

GET /v1/verify/key

La chiave pubblica del verificatore: key_id (SHA-256 della sua SubjectPublicKeyInfo DER), algorithm e public_key (PEM). Con ?key_id= e il kid di un JWS, la chiave che lo ha firmato, comprese quelle con cui non firmiamo più; senza, la più recente.

Una verifica dice cosa contiene un file, non chi l’ha creato né se è stato creato con l’IA: le marcature si possono rimuovere, e un file senza marcature non prova nulla. Il firmatario e la dichiarazione sull’IA sono ciò che ha dichiarato chi ha creato il file.

Errori

Errori degli endpoint del verificatore
StatoCodiceQuando
400invalid_requestNessun file, un campo inviato due volte, signed diverso da true o false, un’immagine illeggibile, oppure un ID della filigrana o un key_id non validi.
400unknown_fieldUn campo diverso da file (o upload) e signed.
401missing_api_key, invalid_api_key, api_key_revokedÈ stato indicato un upload senza la chiave che lo ha creato.
400option_not_availableurl: la verifica di un file tramite URL non è ancora disponibile.
404not_foundNessuna credenziale di provenienza con quell’ID della filigrana, oppure nessuna chiave del verificatore con quel key_id.
404upload_not_foundL’upload indicato non è utilizzabile con questa chiave: sconosciuto, già usato, scaduto o di un’altra chiave.
413payload_too_largeLa richiesta supera i 4 MB: verifica le immagini più grandi sulla pagina del verificatore, oppure invia i file tramite un upload (fino a 25 MB).
415unsupported_media_typeNon è multipart, oppure non è un’immagine, un brano o una clip che sappiamo leggere.
429rate_limitedPiù di 10 verifiche al minuto o 200 al giorno da un solo indirizzo (un indirizzo IPv6 conta per il suo /64; ricerche: 120 al minuto), le verifiche senza chiave di oggi sono esaurite per tutti oppure, con una chiave, le chiamate al minuto della tua organizzazione.
503marker_unavailable, storage_unavailableIl verificatore (o gli upload) non è disponibile, oppure un risultato firmato non ha superato la verifica prima dell’invio. Riprova.