Ein Bild, einen Song oder einen Clip markieren
POST https://api.kennmarq.com/v1/mark
Senden Sie ein Bild oder einen Song, und Sie erhalten die Datei mit einem unsichtbaren Wasserzeichen und einem signierten C2PA-Manifest mit Zeitstempel zurück. Senden Sie einen Clip, und Sie erhalten einen Auftrag und, sobald er fertig ist, den markierten Clip über GET /v1/marks/{id}. Ein Bild zählt eine Markierung, ein Song fünf je angefangene Minute, ein Clip fünf je angefangene Sekunde. Erfordert einen Schlüssel mit der Berechtigung mark.
Anfrage
multipart/form-data mit diesen Feldern. Bei Textfeldern werden Leerzeichen am Anfang und Ende entfernt; Flags akzeptieren true/false (oder 1/0, on/off, yes/no).
| Feld | Typ | Beschreibung |
|---|---|---|
file | Datei, erforderlich (oder upload) | Die Datei: ein Bild im Format PNG, JPEG oder WebP, ein Song im Format MP3, WAV oder M4A oder ein Clip im Format MP4. Ihr Typ wird aus ihren Bytes ermittelt, nicht aus ihrem Namen. Die gesamte Anfrage ist höchstens 4 MB groß; eine größere Datei geht über einen Upload, angegeben in upload: bis 25 MB, ein Clip bis 1 GB. |
upload | Text, statt file | Die ID eines Uploads (up_…) aus POST /v1/uploads, für eine Datei über 4 MB. Sie funktioniert einmal, innerhalb einer Stunde, mit dem Schlüssel, der den Upload erstellt hat. |
source | Text, Standard: created | Wie das Bild entstanden ist, erfasst als sein IPTC Digital Source Type: created (mit KI erstellt), composite (KI kombiniert mit anderem Material) oder edited (ein vorhandenes Bild, mit KI verändert). Sie geben ihn an; wir signieren nur KI-Quelltypen. |
provider | Text, optional | Ihr rechtlicher Name als Anbieter des KI-Systems, z. B. Acme Inc. Zusammen mit app_name und app_version vervollständigt er die latente Offenlegung für Kalifornien. Höchstens 200 Zeichen. |
model | Text, optional | Der Name des Modells, z. B. FLUX.1 schnell. Höchstens 200 Zeichen. |
model_version | Text, optional | Die Version des Modells. Höchstens 200 Zeichen. |
app_name | Text, optional | Der Name Ihres KI-Systems, erfasst als Software-Agent der Aktion „created“. Ohne ihn nennt das Manifest keinen Software-Agenten. Höchstens 200 Zeichen. |
app_version | Text, optional | Die Version Ihres KI-Systems. Erfordert app_name. Höchstens 200 Zeichen. |
markets | Text, optional | Die Märkte, für die die Markierung bestimmt ist, durch Kommas getrennt: der ISO-Code eines beliebigen Landes (de, jp), eu, ein US-Bundesstaat (us-ca) oder us für jeden Bundesstaat mit eigenem Gesetz. Jede Datei erhält, was die Gesetze dieser Länder verlangen (die Weltkarte zeigt sie), ein Aufruf, dem fehlt, was sie brauchen, wird abgelehnt (us-ca und us-wa brauchen provider, app_name und app_version; in braucht app_name), und die Markierung erhält einen signierten Nachweis. in setzt die sichtbare Kennzeichnung auf jedes Bild und jeden Clip. Ein Markt, dessen Regeln etwas verlangen, das wir noch nicht hinzufügen, wird mit option_not_available abgelehnt: China, Deepfakes in Vietnam, Songs in Indien sowie Deepfakes in Songs für eu und kr. |
deepfake | Flag, Standard: false | Die Datei ist ein Deepfake: Sie ähnelt wirklichen Personen, Orten oder Ereignissen und könnte fälschlicherweise als echt erscheinen (Art. 50 Abs. 4 der KI-Verordnung). Das Flag schaltet die sichtbare Kennzeichnung ein; mit eu oder kr in markets lässt sie sich nicht abschalten. Für Songs noch nicht verfügbar. |
label | Flag | Bilder und Clips: die sichtbare KI-Kennzeichnung der EU in die Datei zeichnen, vor dem Wasserzeichen. Standardmäßig aus; eingeschaltet bei Deepfakes und bei in. |
label_language | Text, Standard: en | Das Wort neben „AI“: en (AI GENERATED), ko (AI 생성) oder zh (AI生成). ko ist der Standard, wenn kr in markets steht. |
label_position | Text, Standard: top-right | top-right, top-left, bottom-right oder bottom-left, so wie Betrachter das Bild sehen (die EXIF-Drehung eines Fotos wird berücksichtigt). |
label_size | Text, Standard: medium | small, medium oder large: 5, 7 oder 10 % der kürzeren Seite, mindestens 20 Pixel. in verlangt medium oder large. |
label_style | Text, Standard: auto | auto (schwarz auf einer hellen Ecke, weiß auf einer dunklen), dark, light, dark-translucent oder light-translucent: die vier Varianten des Kodex. |
title | Text, optional | Ein Titel für die Datei. Höchstens 200 Zeichen. |
watermark | Flag, Standard: true | Das unsichtbare Wasserzeichen hinzufügen. Schalten Sie es nur ab, wenn die Datei unseres bereits trägt, z. B. weil sie lokal mit dem Wasserzeichen versehen wurde. |
iptc | Flag, Standard: true | Bilder: den IPTC DigitalSourceType in die XMP-Metadaten der Datei schreiben. Songs und Clips geben ihn in ihrem Manifest an. |
output_format | Text, Standard: keep | Ein Bild: keep, png, jpeg oder webp. Ein Song: keep, mp3, wav oder m4a. Ein Clip: keep oder mp4 (immer H.264 in MP4). |
keep_input_credentials | Flag, Standard: true | Content Credentials, die die Datei bereits trägt (etwa aus der API eines vorgelagerten Modells), als Bestandteil („Ingredient“) behalten, wie es Maßnahme 1.2 des Verhaltenskodex verlangt. |
input | Datei, optional | Für Bearbeitungswerkzeuge: das eigene Eingabebild des Nutzers (bzw. bei einem Song oder Clip ein Eingabesong). Trägt es Content Credentials, bleiben sie als Bestandteil erhalten; sonst wird nichts davon erfasst. Ein Eingabebild wird an unserer Untergrenze gemessen und, mit eingeschaltetem check, an Ihrer Richtlinie. |
input_upload | Text, statt input | Die Upload-ID der Eingabe, für eine Eingabe über 4 MB (oder wenn Datei und Eingabe zusammen über 4 MB groß sind). |
check | Text, Standard: off | Die Sicherheitsprüfung vor dem Markieren: ai-act, safe-only oder off. Bei einer Blockierung wird nichts markiert, und Sie erhalten 422 content_blocked mit dem Grund. Jedes geprüfte Bild zählt zwei Markierungen; ein Clip wird an 12 Einzelbildern geprüft, je zwei Markierungen. Ein Song hat keine Bilder: Lassen Sie die Prüfung ausgeschaltet. |
Geplante Optionen (metadata, webhook, ai_disclosure, categorize, describe, Markieren per url) werden mit 400 option_not_available abgelehnt statt ignoriert, damit eine Datei nie so wirkt, als trüge sie etwas, das sie nicht trägt.
Beispiel
curl https://api.kennmarq.com/v1/mark \
-H "Authorization: Bearer $KENNMARQ_API_KEY" \
-F file=@render.jpg \
-F source=created \
-F provider="Acme Inc." \
-F model="FLUX.1 schnell" \
-F model_version="1.0" \
-F app_name="Acme Studio" \
-F app_version="2.1" \
-F output_format=webp \
-D headers.txt \
-o render.marked.webpimport { readFile, writeFile } from "node:fs/promises";
const form = new FormData();
form.append("file", new Blob([await readFile("render.png")], { type: "image/png" }), "render.png");
form.append("source", "created");
form.append("model", "FLUX.1 schnell");
const res = await fetch("https://api.kennmarq.com/v1/mark", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.KENNMARQ_API_KEY}` },
body: form,
});
if (!res.ok) throw new Error((await res.json()).error.message);
await writeFile("render.marked.png", Buffer.from(await res.arrayBuffer()));
console.log(res.headers.get("x-mark-id"), res.headers.get("x-marks-used"));import os, requests
with open("render.png", "rb") as f:
res = requests.post(
"https://api.kennmarq.com/v1/mark",
headers={"Authorization": f"Bearer {os.environ['KENNMARQ_API_KEY']}"},
files={"file": ("render.png", f, "image/png")},
data={"source": "created", "model": "FLUX.1 schnell"},
timeout=60,
)
res.raise_for_status()
open("render.marked.png", "wb").write(res.content)
print(res.headers["X-Mark-Id"], res.headers["X-Marks-Used"])Antwort
200 mit der markierten Datei als Body und diesen Headern:
| Header | Wert |
|---|---|
Content-Type | Der Typ der markierten Datei: image/png, image/jpeg, image/webp, audio/mpeg, audio/wav oder audio/mp4. |
Content-Disposition | attachment, mit dem Namen der Datei plus .marked und der passenden Endung (image.marked.png für ein hochgeladenes Bild). |
X-Mark-Id | Die ID dieser Markierung (mk_…). Nennen Sie sie dem Support. |
X-Watermark-Id | Die ID, die das Wasserzeichen trägt (hexadezimal). Fehlt bei watermark=false. |
X-Log-Index | Wo die Signatur dieser Datei in unserem öffentlichen Transparenzprotokoll steht: GET /v1/log/proof/{index} beweist, dass sie dort steht. |
X-Marks-Used | Die in diesem Monat in der Umgebung dieses Schlüssels verbrauchten Markierungen, diese eingeschlossen. |
X-Marks-Limit | Das Monatskontingent der Umgebung dieses Schlüssels. |
X-Marks-Counted | Songs: die Markierungen, die dieser Song gezählt hat, fünf je angefangene Minute. |
X-Audio-Watermark | Songs: claimed (die Markierung lässt sich aus der Datei zurücklesen, und ihr Manifest gibt das an), unclaimed (zu leise zum Zurücklesen: Die Datei ist trotzdem signiert) oder off. |
X-Safety-Verdict, X-Safety-Reason | Mit eingeschaltetem check: allow oder flag, dazu der Grund eines flag (sexual_realistic_face: Holen Sie die Einwilligung der Person ein). |
X-Request-Id | Die ID dieser Anfrage (req_…), auch in jedem Fehler-Body. |
X-RateLimit-Limit, -Remaining, -Reset | Siehe Ratenlimits; Reset ist eine Unix-Zeit in Sekunden. |
Sichtbare Kennzeichnungen
Mit eingeschaltetem label zeichnen wir das EU-Symbol aus dem Verhaltenskodex für KI-generierte Inhalte in das Bild oder in jedes Einzelbild des Clips: das großgeschriebene „AI“ und dazu GENERATED bei created oder MODIFIED bei composite und edited, wie es Anhang 1 des Kodex zeigt. Es wird vor dem Wasserzeichen eingefügt, sodass Wasserzeichen und Signatur es abdecken, und das Manifest hält es fest (eine Aktion c2pa.edited und eine Assertion com.kennmarq.label): Das Prüftool und /v1/verify zeigen es an.
Das Symbol sitzt standardmäßig oben rechts, wo es das Beispiel des Kodex platziert, in der Größe nach der kürzeren Seite bemessen, und bei einem Clip auf jedem Einzelbild, wie es der Kodex anregt. auto wählt Schwarz oder Weiß nach den Pixeln dahinter, sodass es auf jedem Hintergrund lesbar bleibt. Ein Bild, das für die Pillenform zu schmal ist, erhält das runde „AI“-Symbol.
deepfake=true schaltet die Kennzeichnung ein, und die Märkte bestimmen, wann sie eingeschaltet bleiben muss: in Indien immer, in der EU und in Südkorea bei Deepfakes. Der Nachweis führt sie für jeden Markt auf.
curl https://api.kennmarq.com/v1/mark \
-H "Authorization: Bearer $KENNMARQ_API_KEY" \
-F file=@portrait.jpg \
-F source=edited \
-F app_name="Acme Studio" \
-F markets=eu,in \
-F deepfake=true \
-o portrait.marked.jpgDieselbe Kennzeichnung in Ihrer eigenen Oberfläche
Neben einer Datei, in einem Feed oder dort, wo ein Bild sie nicht tragen kann, zeigen Sie dieselbe Kennzeichnung mit unserer Webkomponente an: ein Skript, keine Anfragen, keine Cookies, und Screenreader lesen sie als „AI-generated content“ vor. Genau diese Art von Offenlegung verlangt der Kodex neben künstlerischen Werken und Südkorea für Inhalte, die innerhalb Ihres Dienstes angezeigt werden.
<script src="https://kennmarq.com/label.js" defer></script>
<kennmarq-label kind="generated" lang="en" theme="dark" size="24"></kennmarq-label>kind: generated oder modified. lang: en, ko oder zh. theme: dark, light, dark-translucent oder light-translucent. size: die Höhe in Pixeln. href macht die Kennzeichnung zu einem Link, etwa dorthin, wo sich die Datei prüfen lässt. Die Komponente steht unter der MIT-Lizenz: Kopieren Sie sie in Ihre App, wenn Sie sie lieber nicht von uns laden.
Songs
MP3, WAV oder M4A, bis 15 Minuten. Der Song kommt im selben Aufruf zurück, in seinem eigenen Format (oder dem, das output_format nennt), mit seiner Abtastrate, seinen Kanälen und seinen Text-Tags; Coverbilder werden nicht übernommen. Sein Ton trägt die AudioSeal-Markierung von Meta, so unter die Musik geformt, dass niemand sie hört, und sein Manifest wird wie das eines Bildes signiert und mit einem Zeitstempel versehen. Die 16 Bit von AudioSeal sagen, dass die Datei von uns markiert wurde, nicht welche Datei: Die Content Credentials eines Songs stecken in seinem Manifest, und ein Song hat keine X-Watermark-Id.
Die Markierung wird aus der codierten Datei zurückgelesen: Gelingt das, gibt das Manifest an, dass die Datei sie trägt (X-Audio-Watermark: claimed). In einer sehr leisen oder stillen Aufnahme gibt es nichts, worunter sie sich verbergen ließe; die Datei wird dann ohne diese Angabe signiert (unclaimed). Ein Song, der länger ist, als Ihre in diesem Monat verbleibenden Markierungen reichen, wird vor jeder Verarbeitung mit 402 quota_exceeded abgelehnt.
Clips
MP4 (oder QuickTime), bis 4.500 Einzelbilder (2,5 Minuten bei 30 Bildern pro Sekunde, 75 Sekunden bei 60, 5 Minuten bei 15), 1920x1080 im Quer- oder Hochformat, 60 Bilder pro Sekunde, 1 GB über einen Upload: so viel, wie wir innerhalb der Laufzeit eines Auftrags markieren können. Ihr Plan markiert einige Clips gleichzeitig (gleichzeitige Clips). Ein Clip wird als Auftrag markiert: Der Aufruf antwortet sofort mit 202 und der ID der Markierung, und GET /v1/marks/{id} zeigt an, wann er fertig ist, mit einem Link zum Herunterladen. Endpunkte, die Sie im Dashboard hinzufügen, erhalten mark.completed oder mark.failed (Webhooks).
{ "object": "mark", "id": "mk_…", "status": "running", "kind": "clip",
"created_at": "2026-11-12T10:00:00.000Z", "url": "https://api.kennmarq.com/v1/marks/mk_…" }Jedes Einzelbild trägt das Wasserzeichen Video Seal von Meta, mit einer zufälligen ID wie bei einem Bild (watermark_id): Sie führt zu den dauerhaften Content Credentials des Clips, wenn seine Metadaten entfernt wurden. Sein Ton trägt AudioSeal, wie bei einem Song. Der Clip kommt als H.264 in MP4 zurück, aufrecht (die Drehung eines Smartphones wird auf die Pixel angewendet), in derselben Größe, mit denselben Bildzeitpunkten und demselben Ton, signiert und mit Zeitstempel. Bevor er ausgeliefert wird, wird die ID des Wasserzeichens aus 64 seiner Einzelbilder zurückgelesen; ein Clip, aus dem sie sich nicht zurücklesen lässt, schlägt fehl, wie ein Bild. Für unsere Untergrenze werden 12 Einzelbilder jedes Clips gelesen, mit check zusätzlich für Ihre Richtlinie (zwei Markierungen je Einzelbild); ein blockiertes Einzelbild lässt den Auftrag fehlschlagen, mit der Antwort zu diesem Einzelbild in safety.
Was wir vor der Antwort prüfen
Im Zweifel schlagen wir fehl (Fail-closed): Eine Datei geht nur zurück, wenn sie wie verlangt markiert wurde. Vor der Antwort liest der Markierungsdienst die signierte Datei zurück und validiert ihr Manifest und ihren Zeitstempel; dann prüfen wir, dass die Antwort zu dieser Markierung gehört, zu dieser Umgebung, im verlangten Format, mit genau den Bytes, die der Markierungsdienst beschrieben hat. Stimmt etwas nicht, erhalten Sie 502 mark_failed und keine Datei, und die Markierung wird nicht gezählt.
Die Sicherheitsprüfung
Jedes Bild, das wir markieren, wird an unserer eigenen Untergrenze gemessen, was auch immer Sie senden: Explizite Inhalte mit einer Person, die dem Anschein nach ein Kind ist, werden nie markiert, und der Aufruf antwortet mit 422 content_blocked. Ist check gesetzt, werden die Datei und die Eingabe zusätzlich nach Ihrer Richtlinie geprüft. Bei einem Clip werden 12 Einzelbilder gelesen. Eine Blockierung antwortet mit der Prüfung in safety, und picture gibt an, welches Bild es war:
{
"error": { "code": "content_blocked", "message": "The safety check blocked this picture, so nothing was marked. See \"safety\" for why.", "request_id": "req_…" },
"safety": { "object": "safety_check", "policy": "ai-act", "verdict": "block", "reason": "sexual_apparent_minor",
"nudity": { "label": "explicit", "score": 0.98 }, "apparent_minor": true, "realistic_face": true,
"picture": "file", … }
}Ein blockierter Aufruf zählt die durchgeführten Prüfungen, nicht die Markierung. Eine Blockierung allein durch unsere Untergrenze, bei ausgeschaltetem check, zählt nichts.
Fehler
| Status | Code | Wann |
|---|---|---|
| 400 | invalid_request | Keine Datei, ein doppelt gesendetes Feld oder eine Option außerhalb des zulässigen Bereichs. |
| 400 | unknown_field | Ein Feld, das dieser Endpunkt nicht kennt: Ein Tippfehler geht nie unbemerkt durch. |
| 400 | option_not_available | Eine geplante Option wie metadata oder webhook, oder ein Markt, dessen Regeln etwas verlangen, das wir noch nicht hinzufügen (China, Vietnam, Songs in Indien). |
| 401 | missing_api_key, invalid_api_key, api_key_revoked | Siehe Authentifizierung. |
| 402 | quota_exceeded | Das Monatskontingent an Markierungen oder Daten ist aufgebraucht, oder ein Song braucht mehr Markierungen, als noch übrig sind (es wird nichts markiert). |
| 403 | insufficient_scope, ip_not_allowed | Dem Schlüssel fehlt die Berechtigung mark, oder die Adresse steht nicht auf der Allowlist. |
| 404 | upload_not_found | Der angegebene Upload ist keiner, den dieser Schlüssel verwenden kann: unbekannt, schon verwendet, abgelaufen oder der eines anderen Schlüssels. |
| 413 | payload_too_large | Die Anfrage ist größer als 4 MB (senden Sie größere Dateien über einen Upload), oder die Datei überschreitet unsere Grenzen: Songs 15 Minuten, Clips 4.500 Einzelbilder mit bis zu 1920x1080. |
| 415 | unsupported_media_type | Kein Bild, Song oder Clip, den wir annehmen, oder nicht als multipart/form-data gesendet. |
| 422 | content_blocked | Die Sicherheitsprüfung hat die Datei oder die Eingabe blockiert. Das Feld safety im Body nennt den Grund; es wurde nichts markiert. |
| 429 | rate_limited | Zu viele Aufrufe in dieser Minute (alle Schlüssel Ihrer Organisation zusammen), heute zu viele Aufrufe, die fehlgeschlagen sind, nachdem wir sie bearbeitet hatten, oder (bei einem Clip) es laufen bereits so viele Clips gleichzeitig, wie Ihr Plan erlaubt, oder zu viele Clips sind fehlgeschlagen: Versuchen Sie es nach Retry-After Sekunden erneut. |
| 502 | mark_failed | Die Datei konnte nicht markiert und verifiziert werden; es wird keine Datei zurückgegeben. Es wird nichts berechnet. |
| 503 | marker_unavailable, storage_unavailable | Der Markierungsdienst oder die Uploads sind kurzzeitig nicht verfügbar. Es wird nichts berechnet; versuchen Sie es erneut. |
Fehler-Bodys folgen dem gemeinsamen Format.
Datenschutz
Wir erfassen von jeder Markierung die ID, die Wasserzeichen-ID, den SHA-256 und die Größen, nie die Datei, ihren Namen oder ihren Inhalt. Die markierte Datei eines Clips liegt einen Tag für Sie bereit und wird dann gelöscht. Markierungen geben an, wie eine Datei entstanden ist, nie, wer sie erstellt hat oder mit welchem Prompt. Die Antwort einer Sicherheitsprüfung wird nie in die Markierungen der Datei geschrieben, und von einem blockierten Bild wird nichts aufbewahrt. Ein Upload wird gelöscht, sobald der Aufruf ihn verwendet hat.