Il controllo di sicurezza
POST https://api.kennmarq.com/v1/check
Dal 2 dicembre 2026 l’AI Act vieta i sistemi di IA che creano immagini sessuali di chiunque sembri un minore, o di una persona reale senza il suo consenso (art. 5, par. 1, lett. b bis e b ter). Il controllo di sicurezza cerca entrambi i casi in un’immagine, con un esito tra blocco, segnalazione e via libera. È un segnale di rischio con tassi di errore pubblicati, non una garanzia: decidi tu, e la responsabilità resta tua.
Richiesta
Una chiave con l’ambito check e una richiesta multipart/form-data con l’immagine in file (PNG, JPEG o WebP; la richiesta è al massimo di 4 MB, e un’immagine più grande, fino a 25 MB, passa da un upload indicato in upload) e, facoltativamente, policy: ai-act (il valore predefinito) o safe-only. Ogni controllo conta due marcature. Per controllare un file mentre lo marchi, invia invece check a POST /v1/mark.
Una clip (MP4, qui fino a 25 MB; una più grande va controllata mentre la marchi) viene letta su 12 fotogrammi distribuiti lungo la sua durata, due marcature ciascuno: la risposta è quella del fotogramma peggiore (un blocco prevale su una segnalazione, una segnalazione su un via libera), con la posizione di quel fotogramma in frame (index e seconds) e in frames il numero di fotogrammi letti.
curl https://api.kennmarq.com/v1/check \
-H "Authorization: Bearer $KENNMARQ_API_KEY" \
-F file=@render.png -F policy=ai-act{
"object": "safety_check",
"checked_at": "2026-11-12T10:00:00Z",
"checker": { "name": "Kennmarq.com", "version": "0.5.0" },
"file": { "type": "image/png", "bytes": 1482113, "width": 1024, "height": 1024, "sha256": "…" },
"policy": "ai-act",
"verdict": "flag",
"reason": "sexual_realistic_face",
"nudity": { "label": "explicit", "score": 0.991 },
"apparent_minor": false,
"realistic_face": true
}verdict:allow,flagoblock. Anche un blocco è un200: il controllo ha funzionato, e la sua risposta è il blocco.reason:sexual_apparent_minor,sexual_realistic_face,explicit, oppurenullper un via libera.nudity:none,suggestiveoexplicit, e il punteggio del classificatore, da 0 a 1.apparent_minorerealistic_face: valutati solo per un’immagine con nudità, altrimentinull. Il controllo non stima mai l’età fine a sé stessa e non restituisce mai un’età né un’identità.
Policy
| Policy | Blocca | Segnala |
|---|---|---|
ai-act | Contenuti sessuali o allusivi con una persona apparentemente minorenne (art. 5, par. 1, lett. b ter) | Contenuti espliciti con un volto realistico: ottieni il consenso della persona prima di pubblicarli (art. 5, par. 1, lett. b bis) |
safe-only | Lo stesso, e qualsiasi contenuto esplicito | Nulla |
| la nostra soglia minima | Contenuti espliciti con una persona apparentemente minorenne, su ogni POST /v1/mark, qualunque sia il suo check. Non si può disattivare | Nulla |
Come viene letta un’immagine
Per passi, ciascuno solo se il precedente lo richiede, così un’immagine senza nudità costa una sola lettura. Prima la nudità: explicit quando il classificatore è sicuro, oppure abbastanza sicuro e il rilevatore trova una parte esposta; suggestive da un punteggio di 0,3. Poi, per un’immagine con nudità: è una foto? In una foto, ogni volto abbastanza grande da essere letto (32 px o più) viene valutato per l’età apparente, con soglie più severe su un’immagine esplicita che su una allusiva. Un disegno passa invece al tagger, i cui tag indicano quando un personaggio disegnato è un bambino.
| Lettura | Modello | Licenza |
|---|---|---|
| Nudità | Il classificatore NSFW di Falconsai (ViT-B/16), con il rilevatore 320n di NudeNet come secondo parere sulle immagini al limite | Apache-2.0; MIT |
| Foto o disegno | SigLIP di Google (base, 224 px), zero-shot su descrizioni di foto e di disegni | Apache-2.0 |
| Volti | YuNet di OpenCV Zoo | MIT |
| Età apparente, foto | Due modelli su sei ritagli di ogni volto: SigLIP 2 con fine-tuning su fasce d’età e age-vit di Civitai | Apache-2.0 |
| Età apparente, disegni | wd-vit-tagger-v3 di SmilingWolf (i suoi tag che indicano un bambino) | Apache-2.0 |
Tutti modelli aperti, eseguiti sui nostri server a Zurigo e fissati esattamente ai file che abbiamo testato.
Tassi di errore
Quota di foto reali il cui volto è stato valutato come minorenne, misurata a ottobre 2026 con questi modelli e queste soglie sulle foto di validazione di FairFace (5.980 volti):
| Età | Immagine esplicita | Immagine allusiva |
|---|---|---|
| 0–2 | 98,5% | 97% |
| 3–9 | 92% | 85% |
| 10–19 | 47% | 34% |
| 20–29 | 5,9% | 2,3% |
| 30 e oltre | 0,9% | 0,6% |
Gli adulti valutati come minorenni nelle immagini esplicite non sono distribuiti in modo uniforme: tra i 20 e i 29 anni, donne 8,0% e uomini 3,2%; volti neri e del Sud-est asiatico circa 12,5%, volti bianchi 1,7%. FairFace è il set di addestramento di uno dei modelli, quindi sulle immagini reali i risultati saranno peggiori. Su immagini comuni senza nudità, il controllo non ha dato alcun falso allarme su 78, con l’una e con l’altra policy (il rapporto di robustezza). Limiti noti:
- un volto che non trova (girato, nascosto o alto meno di 32 px) non riceve alcuna stima dell’età, quindi una foto del genere passa;
- intorno ai 18 anni l’età apparente è una stima incerta, in entrambe le direzioni: la maggior parte degli adolescenti più grandi passa;
- un rendering 3D quasi fotorealistico conta come una foto;
- il tagger legge meglio i disegni in stile anime; altri stili possono nascondere un bambino disegnato.
Privacy
L’immagine viene letta in memoria e mai conservata: nessuna copia, nessun punteggio, nessun hash. La risposta arriva solo a te, mai nelle marcature di un file.
Errori
| Stato | Codice | Quando |
|---|---|---|
| 400 | invalid_request | Nessun file, un campo inviato due volte, una policy diversa da ai-act o safe-only, oppure un’immagine illeggibile. |
| 400 | unknown_field | Un campo diverso da file (o upload) e policy. |
| 400 | option_not_available | url, categorize o describe: non ancora disponibili. |
| 401 | missing_api_key, invalid_api_key, api_key_revoked | Vedi la pagina Autenticazione. |
| 402 | quota_exceeded | Restano meno di due marcature questo mese (24 per una clip). |
| 403 | insufficient_scope, ip_not_allowed | La chiave non ha l’ambito check, oppure l’indirizzo non è tra gli IP consentiti. |
| 404 | upload_not_found | L’upload indicato non è utilizzabile con questa chiave: sconosciuto, già usato, scaduto o di un’altra chiave. |
| 413 | payload_too_large | La richiesta supera i 4 MB (invia i file più grandi tramite un upload), oppure una clip supera i 25 MB o i nostri limiti. |
| 415 | unsupported_media_type | Non è un’immagine PNG, JPEG o WebP né una clip MP4, oppure non è stata inviata come multipart/form-data. |
| 429 | rate_limited | Troppe chiamate in questo minuto; riprova dopo i secondi indicati da Retry-After. |
| 503 | marker_unavailable, storage_unavailable | Il controllo (o gli upload) non può essere eseguito in questo momento. Non viene mai saltato: non viene addebitato nulla; riprova. |
Il body degli errori segue il formato comune.