Salta al contenuto

Documentazione API

Tutto ciò che trovi di seguito è generato dalle stesse definizioni utilizzate dal motore, quindi non può descrivere funzionalità di cui il codice è privo.

Descrizione OpenAPI leggibile da macchine: /api/v1/openapi.json

Autenticazione

Invia la tua chiave in uno dei due header. Entrambi sono equivalenti.

Authorization: Bearer nmd_live_xxxxxxxxxxxxxxxx
X-API-Key: nmd_live_xxxxxxxxxxxxxxxx

Le chiavi si creano nella tua dashboard. Una chiave viene mostrata una sola volta e memorizzata solo come hash: se la perdi, revocala e creane un’altra.

POST /api/v1/analyze

Legge ogni campo di metadati presente nel file e restituisce il modello normalizzato.

curl -X POST https://your-domain/api/v1/analyze \
  -H "Authorization: Bearer $NMD_KEY" \
  -F "file=@photo.jpg"

La risposta raggruppa i campi per categoria e mantiene i valori originali non tradotti sotto raw:

{
  "file": { "name": "photo.jpg", "format": "jpeg", "size": 4821904 },
  "counts": { "total": 31, "removable": 26, "sensitive": 16 },
  "blocks": { "exif": { "present": true, "count": 29 }, "gps": { "present": true } },
  "metadata": {
    "camera": {
      "camera.make": { "label": "Make", "value": "Apple", "sensitive": true, "removable": true }
    }
  }
}

POST /api/v1/clean

Rimuove i metadati, quindi rilegge i byte prodotti per verificare il risultato. Restituisce il file pulito per impostazione predefinita, oppure il solo report con <code>response=json</code>.

ParametroValoriPredefinito
modequick, fullquick
keepCopyright0, 10
keepColorProfile0, 1quick: 1, full: 0
keepOrientation0, 1quick: 1, full: 0
removeC2pa0, 10
responsefile, jsonfile
curl -X POST https://your-domain/api/v1/clean \
  -H "Authorization: Bearer $NMD_KEY" \
  -F "file=@video.mp4" -F "mode=full" -OJ

removeC2pa è disattivato per impostazione predefinita e non viene attivato da mode=full. Una normale pulizia dei metadati non rimuove mai le Content Credentials C2PA: cancellare la storia di provenienza di un file è un’istruzione distinta che il chiamante deve richiedere esplicitamente.

Quando viene restituito un file, nell’header X-NoMoreData-Result viaggia codificato in URL un riepilogo del report di verifica: i valori scalari testuali — verified è true solo quando la ri-analisi non ha riscontrato residui inattesi — e ogni elenco come conteggio, removedCount, residualCount e così via. Si decodifica e si analizza sempre. Per gli elenchi stessi, chiedi response=json.

POST /api/v1/edit

Applica modifiche ai campi. <code>value: null</code> elimina un campo. I campi al di fuori del registro scrivibile vengono segnalati in <code>warnings</code> anziché essere scartati silenziosamente.

ParametroValoriPredefinito
editsJSON array of {key, value}required
replaceAll0, 10
removeC2pa0, 10
responsefile, jsonfile

replaceAll rimuove i blocchi di metadati esistenti. Non rimuove le Content Credentials C2PA: per quello c’è removeC2pa, disattivato per impostazione predefinita. Se sostituisci tutto lasciando la credenziale, la risposta lo indica chiaramente.

curl -X POST https://your-domain/api/v1/edit \
  -H "Authorization: Bearer $NMD_KEY" \
  -F "file=@photo.jpg" \
  -F 'edits=[{"key":"camera.make","value":"Canon"},{"key":"location.latitude","value":null}]' \
  -F "response=json"

POST /api/v1/apply-profile

Scrive un set coerente di campi tipici di un dispositivo. Gli ID dei profili si ottengono da <code>GET /api/profiles</code>.

curl -X POST https://your-domain/api/v1/apply-profile \
  -H "Authorization: Bearer $NMD_KEY" \
  -F "file=@photo.jpg" -F "profile=canon-eos-r5" -F "iso=400"

L’applicazione di un profilo scrive metadati tipici di un dispositivo. Non attesta e non può attestare che il file abbia avuto origine da tale dispositivo: i metadati sono modificabili per progettazione e non costituiscono una prova di provenienza. Ogni risposta include questo disclaimer.

Altri linguaggi

JavaScript

const body = new FormData();
body.append('file', file);           // a File or Blob
body.append('mode', 'full');
body.append('response', 'json');

const res = await fetch('https://your-domain/api/v1/clean', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.NMD_KEY}` },
  body,
});

const report = await res.json();
console.log(report.verified, report.removed.length);

Python

import os, requests

with open("photo.jpg", "rb") as fh:
    response = requests.post(
        "https://your-domain/api/v1/clean",
        headers={"Authorization": f"Bearer {os.environ['NMD_KEY']}"},
        files={"file": fh},
        data={"mode": "full", "response": "json"},
    )

report = response.json()
print(report["verified"], len(report["removed"]))

Errori

Tutti gli errori condividono la stessa struttura e non espongono mai dettagli interni né tracce dello stack.

{ "error": { "code": "unsupported_format", "message": "GIF is not supported.", "hint": "..." } }
CodiceStato HTTPSignificato
missing_api_key401Nessuna chiave API fornita.
invalid_api_key401La chiave è sconosciuta, revocata o non valida.
plan_required403Il tuo piano attuale non include l’accesso alle API.
missing_file400Nessun file presente nella richiesta multipart.
invalid_request400Un parametro era mancante o malformato.
file_too_large413Il file supera il limite di dimensione consentito dal tuo piano.
unsupported_format415Il formato del file non è supportato.
corrupt_file422Impossibile analizzare il file: potrebbe essere danneggiato.
unsupported_operation422File valido, ma l’operazione richiesta non è implementata per questo formato.
rate_limited429Troppe richieste in un breve intervallo di tempo.
quota_exceeded429Hai esaurito la quota di chiamate mensili prevista dal tuo piano.

Limiti di frequenza e quote

Si applicano due limiti: un rate limit a breve termine per indirizzo IP per proteggere il servizio e la quota mensile di chiamate prevista dal tuo piano. Le risposte andate a buon fine includono la quota rimanente.

X-RateLimit-Limit: 2000
X-RateLimit-Remaining: 1834
X-RateLimit-Reset: 1767225600

Un rifiuto per superamento quota restituisce HTTP 429 con codice quota_exceeded e un header Retry-After. L’utilizzo viene conteggiato solo per le richieste che hanno effettivamente eseguito lavoro: una richiesta rifiutata non consuma la tua quota.

Formati supportati

FormatoAnalizzaPulisciModifica
JPEGsìsìsì
PNGsìsìsì
WebPsìsìsì
HEIC/HEIFsìsìsì
AVIFsìsìsì
MP4sìsìsì
QuickTime MOVsìsìsì
WebMsìsìno
PDFsìsìsì
MP3sìsìsì
WAVsìsìsì
M4Asìsìsì

Un’operazione non implementata per un formato restituisce 422 unsupported_operation invece di restituire il file invariato.

Campi scrivibili (28)

Chiavi accettate da /api/v1/edit. Ciascuna di esse è supportata da un encoder dedicato.

ChiaveCampo
camera.makeMake
camera.modelModel
camera.lensMakeLens make
camera.lensModelLens model
camera.serialNumberBody serial number
camera.lensSerialNumberLens serial number
capture.isoISO
capture.exposureTimeExposure time
capture.fNumberAperture (f-number)
capture.focalLengthFocal length
capture.focalLength35mmFocal length (35 mm equiv.)
capture.exposureBiasExposure compensation
capture.exposureProgramExposure program
capture.meteringModeMetering mode
capture.whiteBalanceWhite balance
capture.flashFlash
capture.colorSpaceColour space
capture.orientationOrientation
date.originalDate taken
date.digitizedDate digitised
date.modifiedFile change date
general.softwareSoftware
general.artistArtist
general.copyrightCopyright
general.descriptionImage description
location.latitudeLatitude
location.longitudeLongitude
location.altitudeAltitude

Come vengono gestiti i tuoi file

Un file inviato all’API viene mantenuto in memoria per la sola durata della richiesta, utilizzato unicamente per l’operazione desiderata e rilasciato insieme alla risposta. Nulla viene memorizzato su disco, archiviato, registrato o impiegato per addestramento o statistiche.

Questo si differenzia dal sito web, che elabora i file interamente nel browser senza caricare nulla. Se la tua integrazione può essere eseguita lato client, quella rimane l’opzione consigliata per la massima riservatezza.