Clip MasterClipMaster

ClipMaster API

Automatisier ClipMaster über die Kommandozeile, eigene Skripte oder einen KI-Assistenten. Dieselben Endpunkte wie in der App – abgerechnet mit denselben Tokens, ohne separate Rechnung.

Lieber reiner Text? Diese Seite als Markdown lesen – gemacht für LLMs und Agents. Nutzt du Claude? Verbinde den MCP-Server – dann musst du keine Endpunkte von Hand aufrufen.

Überblick

Greif mit einem API-Schlüssel per Code auf ClipMaster zu. Jeder Endpunkt verhält sich genau wie in der App, beschränkt auf deine eigenen Projekte und Clips. API-Zugang gibt es in den Bezahlplänen.

Basis-URL:

https://api.clipmaster.app/api/v1

Authentifizierung

Erstell einen Schlüssel in der App unter Einstellungen → API-Zugang. Der vollständige Schlüssel (cm_live_…) wird nur einmal beim Erstellen angezeigt – bewahr ihn sicher auf. Sende ihn als Bearer-Token im Authorization-Header:

curl https://api.clipmaster.app/api/v1/projects \
-H "Authorization: Bearer cm_live_xxxxxxxxxxxxxxxxxxxx"
  • Nur im Header. Schlüssel werden nicht als ?token=-Query-Parameter akzeptiert.
  • Ein Schlüssel gehört zu deinem Konto und handelt in deinem Namen, beschränkt auf deine eigenen Daten.
  • Du kannst einen Schlüssel jederzeit in den Einstellungen widerrufen; ein widerrufener Schlüssel funktioniert sofort nicht mehr.
Routen zur Kontoverwaltung bleiben in der App. Ein Schlüssel gibt 403 session_auth_required zurück für Login/OAuth, Abrechnung und Checkout (das Lesen deines Token-Guthabens und deiner Nutzung ist erlaubt), Admin, API-Schlüsselverwaltung und das Verbinden eines sozialen Kanals. Verbinde deinen Kanal zuerst in der Web-App – alles andere ist skriptfähig.

Einige Endpunkte sind Funktionen kostenpflichtiger Pläne, unten mit dem Funktionsnamen gekennzeichnet (zum Beispiel compilation). Bei einem Plan ohne diese Funktion antworten sie mit 403 subscription_required und der feature.

Rate Limits

120 Requests pro Minute und Schlüssel. Darüber hinaus gibt's 429 mit einem Retry-After-Header.

Die KI-Endpunkte (Vorschläge, Auto-edit, Audiomessung, Anordnung) haben auch ihre eigenen Limits pro Benutzer und antworten auf die gleiche Weise mit 429.

Schnellstart

Importier ein YouTube-Video, warte auf die Verarbeitung, dann liste die Clips auf und lade sie herunter. Setz diese Variablen einmal in deiner Shell:

KEY="cm_live_xxxxxxxxxxxxxxxxxxxx"
BASE="https://api.clipmaster.app/api/v1"
1Video per URL importieren

Anfrage

curl -X POST "$BASE/upload/from-url" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"source_url": "https://youtube.com/watch?v=..."
}

Antwort

{
"project_id": 123,
"task_id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890",
"message": "Processing started",
"progress_url": "/api/v1/projects/123/status"
}
2Status abfragen, bis die Verarbeitung fertig ist

Anfrage

curl "$BASE/projects/123/status" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"status": "completed",
"progress": 1.0,
"progress_percent": 100,
"total_clips": 6,
"processing_complete": true
}
3Erzeugte Clips auflisten

Anfrage

curl "$BASE/projects/123/clips" \
-H "Authorization: Bearer $KEY"

Antwort

[
{
"clip_id": 456,
"start_time": 0.0,
"end_time": 42.3,
"description": "Founder explains the pivot",
"status": "ready"
}
]
4Exportieren, dann herunterladen

Anfrage

# Render it (charges tokens) -> {"export_id": 37, "status": "rendering", ...}
curl -X POST "$BASE/projects/123/clips/456/export" \
-H "Authorization: Bearer $KEY"
# Poll until "status" is "completed"
curl "$BASE/exports/37/status" -H "Authorization: Bearer $KEY"
# The clip's exports, newest first
curl "$BASE/exports?clip_id=456" -H "Authorization: Bearer $KEY"
# Download from the newest completed export's download_url
curl -L "$DOWNLOAD_URL" -o clip.mp4

Ein Download ist immer ein Export: der Clip, gerendert mit seinen gespeicherten Untertiteln, Effekten und dem Trim. download_url ist ein signierter S3-Link, gültig bis zum nächsten 00:00 UTC (mindestens 30 Minuten) – ohne Auth-Header. Für einen neuen Link einfach erneut GET /exports aufrufen.

Upload

Für Dateien verwende den zweistufigen Upload-Flow; für YouTube, importiere per URL. Beide akzeptieren die gleichen optionalen Felder: processing_mode (automatic, semantic oder full_video), query, min_duration, orientation, die Untertitel-Flags und compilation_format mit compilation_prompt, um eine Compilation zu erstellen, sobald die Clips bereit sind. Die Verarbeitung kostet 1 Token pro Quellminute.

POST/upload/from-url

Eine YouTube-URL importieren. Die Verarbeitung beginnt sofort; frage den Status des zurückgegebenen Projekts ab. Kostenpflichtig: youtube_import.

Anfrage

curl -X POST "$BASE/upload/from-url" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"source_url": "https://youtube.com/watch?v=...",
"orientation": "vertical",
"compilation_format": "auto"
}

Antwort

{
"project_id": 123,
"task_id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890",
"message": "Processing started",
"metadata": { "duration_sec": 212.4, "resolution": "1920x1080" },
"progress_url": "/api/v1/projects/123/status"
}
POST/uploads/init

Schritt 1 eines Datei-Uploads. Liefert ein kurzlebiges Upload-Ziel: Schick die Datei per POST an upload.url, mit den zurückgegebenen upload.fields unverändert, und ruf dann complete auf.

Anfrage

curl -X POST "$BASE/uploads/init" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"filename": "talk.mp4",
"size_bytes": 94371840,
"sha256": "e3b0c44298fc1c14...",
"duration_sec": 693.5,
"content_type": "video/mp4"
}

Antwort

{
"project_id": 124,
"upload": {
"url": "https://uploads.clipmaster.app",
"fields": {
"...": "opaque form fields - send them back unchanged"
}
},
"expires_at": "2026-08-14T21:00:00Z"
}
POST/uploads/{project_id}/complete

Schritt 2: Bestätigt, dass der Upload fertig ist, und startet die Verarbeitung.

Anfrage

curl -X POST "$BASE/uploads/124/complete" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 124,
"task_id": "b2c3d4e5-...",
"message": "Processing started",
"progress_url": "/api/v1/projects/124/status"
}
POST/uploads/assets

Ein Logo, ein Voiceover oder eine Compilation-Szenendatei ohne Browser hochladen. purpose ist logo, narration, scene_video oder scene_image (die letzten beiden kostenpflichtig: compilation). POSTe die zurückgegebenen Felder, dann die Datei zuletzt, an upload.url innerhalb von 15 Minuten, dann verwende den asset_key unter /users/me/logo/from-upload, /projects/{id}/clips/{clip_id}/logo/from-upload, /compilations/{id}/narration/from-upload oder /compilations/{id}/media-scenes (als upload_key).

Anfrage

curl -X POST "$BASE/uploads/assets" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"purpose": "logo", "content_type": "image/png", "size_bytes": 20480}'

Antwort

{
"asset_key": "originals/staging/42/9f1c2b7e.png",
"upload": {
"url": "https://s3.amazonaws.com/...",
"fields": { "...": "opaque form fields - send them back unchanged" }
},
"expires_at": "2026-09-11T21:15:00Z"
}

Status & Clips

GET/projects/{id}/status

Fragt den Verarbeitungsfortschritt ab. status ist einer von uploading, uploaded, processing, completed, failed.

Anfrage

curl "$BASE/projects/123/status" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"status": "processing",
"progress": 0.45,
"progress_percent": 45,
"current_step": "Transcription",
"total_scenes": 8,
"total_clips": 0,
"processing_complete": false
}
GET/projects/{id}/clips

Listet erzeugte Clips mit KI-Metadaten auf (Hook, Clip-Typ, Konfidenz).

Anfrage

curl "$BASE/projects/123/clips" \
-H "Authorization: Bearer $KEY"

Antwort

[
{
"clip_id": 456,
"start_time": 0.0,
"end_time": 42.3,
"description": "Founder explains the pivot",
"display_name": null,
"status": "ready",
"source": "Clipmaster",
"streaming_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...",
"features": {
"scene_id": 2265,
"clip_duration": 42.3,
"vision_analysis": {
"hook": "The moment everything changed",
"clip_type": "story",
"confidence": 0.9
}
}
}
]
GET/projects/{id}/clips/{clip_id}

Volle Details für einen Clip – eine Obermenge des Listenelements: jedes Feature-Feld, die KI-Analyse der Szene, ihr Padding, Badge und Viralität. Jeder Frame, der Ton und die Wörter sind in GET …/analysis.

Anfrage

curl "$BASE/projects/123/clips/456" \
-H "Authorization: Bearer $KEY"

Gleiche Struktur wie der Listeneintrag oben, mit dem vollständigen features-Objekt.

GET/projects

Listet deine Projekte auf.

Anfrage

curl "$BASE/projects" -H "Authorization: Bearer $KEY"

Antwort

[
{
"project_id": 123,
"filename": "keynote.mp4",
"status": "completed",
"created_at": "2026-08-14T20:11:38Z",
"video_metadata": {
"duration_sec": 693.5,
"resolution": "1920x1080",
"detected_orientation": "horizontal"
},
"is_demo": false
}
]
DELETE/projects/{id}

Löscht ein Projekt mit allen Clips, Szenen und Dateien.

Anfrage

curl -X DELETE "$BASE/projects/123" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"success": true,
"message": "Project deleted"
}
POST/projects/{id}/transcription

Das gesamte Video im Hintergrund erneut transkribieren. Clips mit eigenen bearbeiteten Wörtern behalten diese. Frage den Status für project_config.transcription_rerun_status ab. Keine Tokens; ratenbegrenzt.

Anfrage

curl -X POST "$BASE/projects/123/transcription" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"status": "running",
"progress_url": "/api/v1/projects/123/status"
}

Analyse

Lies die Analyse als JSON zurück, um einen Schnitt auf das Gefundene zu platzieren. Die Dokumente eines Clips verwenden die Zeit des Viewers – die Uhr der Overlays, Vorschläge und Auto-Edit: Sekunden ab dem Start der Szene. Der Clip spielt von 0 bis time.duration; Zeiten außerhalb davon sind die Polsterung um die Szene herum, wo Overlays nicht platziert werden können. Die Momentliste behält nur das, was abgespielt wird, sodass jedes t so platziert werden kann, wie es ist; aus der vollständigen Clip-Analyse platziere nur Zeiten zwischen 0 und time.duration. Videosekunden = t + time.scene_start. Das Dokument des Videos verwendet Sekunden ab dem Start des Uploads. Boxen sind {x, y, w, h} Bruchteile des Frames. Das Lesen ist kostenlos und funktioniert im Demo-Projekt.

GET/projects/{id}/clips/{clip_id}/analysis

Die gesamte gespeicherte Analyse eines Clips. Abschnitte: scene (Beschreibung, Hook, Thema, Typ, Score, Badge, Viralität), layout (Kameraschnitte und, pro Frame, der Shot-Typ, Gesichter und Bildschirm-/Webcam-Panels), audio (laut, leise, Beat, Gesang; onsets=true fügt jeden Hit hinzu), transcript (die Wörter des Clips, mit Sprechern, wenn bekannt), sound_events (Lachen, Applaus, Musik), video_moments, talk_scenes und auto_edit (der gespeicherte Take, mit seinen Geschwindigkeitsbereichen). include wählt Abschnitte, kommagetrennt; standardmäßig alle.

Anfrage

curl "$BASE/projects/123/clips/456/analysis?include=scene,layout,audio" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"clip_id": 456,
"scene_id": 2265,
"time": {
"clock": "viewer",
"unit": "seconds",
"note": "0 = scene start, …",
"duration": 10.0,
"scene_start": 100.0,
"scene_end": 110.0,
"clip_start": -2.0,
"clip_end": 12.0
},
"analyses": {
"layout": {
"status": "completed",
"error": null,
"step": null,
"started_at": "2026-10-22T18:02:11+00:00",
"finished_at": "2026-10-22T18:02:40+00:00",
"what": "Faces, screen/webcam/gameplay panels, shot type per frame, camera cuts.",
"rest": "POST /api/v1/projects/123/clips/456/layout-analysis",
"mcp": "analyze_clip_layout",
"cost": "Paid plans (smart crop); no tokens."
},
"audio_cues": { "status": "completed", "...": "same fields" },
"auto_edit": { "status": null, "...": "same fields" }
},
"scene": {
"description": "He grabs the rim and the crowd erupts",
"hook": "The dunk nobody saw coming",
"topic": "basketball",
"clip_type": "reaction",
"score": 8,
"...": "the rest of its stored AI fields",
"badge": { "label": "Highlight", "key": "highlight", "color": "#FF6B6B" },
"virality": { "tier": "hot", "label": "Hot", "color": "#FF4444" }
},
"layout": {
"current": true,
"faces_placeable": true,
"analyzed_at": "2026-10-22T18:02:40+00:00",
"model": "gemini-3.5-flash-lite",
"frame_interval": 2.0,
"frame_size": { "width": 1920, "height": 1080 },
"cuts": [4.0],
"frames": [
{ "t": 0.0, "shot": "solo_talking_head",
"faces": [{ "x": 0.4, "y": 0.1, "w": 0.2, "h": 0.4 }], "panels": [] },
{ "t": 4.0, "shot": "screen_share_with_webcam",
"faces": [{ "x": 0.8, "y": 0.04, "w": 0.12, "h": 0.18 }],
"panels": [{ "kind": "webcam_overlay", "x": 0.75, "y": 0.0, "w": 0.25, "h": 0.25,
"highlighted": true }] }
]
},
"audio": {
"current": true,
"measured_at": "2026-10-22T18:01:05+00:00",
"has_audio": true,
"median_active_db": -20.0,
"loud": [{ "t": 4.0, "end": 4.5, "over_db": 9.0 }],
"quiet": [{ "start": -2.0, "end": -0.5, "level_db": -48.0 }],
"beat": [{ "start": 0.0, "end": 10.0, "tempo_bpm": 120.0, "first_beat": 0.1, "period": 0.5 }],
"singing": null
}
}

time und analyses sind immer vorhanden. analyses hat einen Eintrag pro On-Demand-Lauf (layout, audio_cues, auto_edit): status ist running, completed, failed, stale (seit über 30 Minuten als running markiert, ist also wahrscheinlich abgestürzt – vor dem Neustart erneut prüfen) oder null (nie ausgeführt), mit error, step (der zuletzt erreichte Schritt; aussagekräftig während der Ausführung), Zeitstempeln und dem Endpunkt, der ihn startet. layout, audio und auto_edit sind null, bis sie ausgeführt wurden; sound_events, video_moments und talk_scenes sind [], wenn nichts gefunden wurde. current: false bedeutet, dass das Ergebnis nicht mehr zum Clip passt: Die Videodatei wurde seitdem erneut geschnitten (ein Trim allein ändert es nicht), für layout auch, wenn der letzte Lauf nicht abgeschlossen wurde, für audio auch, wenn sich die Messung selbst geändert hat. Ein Trim macht auto_edit current: false, da seine Zeiten auf der Uhr der Szene liegen; eine ältere Aufnahme, die ihre Szene nicht aufgezeichnet hat, liest current: null (unbekannt). Audiozeiten werden aus der Datei konvertiert, auf der sie gemessen wurden. Ein unbekannter Abschnitt ist 400 unknown_section.

GET/projects/{id}/clips/{clip_id}/moments

Der Clip als eine zeitlich sortierte Liste von {t, kind, source, …}: cut, shot und faces (wenn sich die Aufnahme- oder Gesichtszahl ändert), speaker-Wechsel, sound, loud, quiet, beat, singing und die moments des Vision-Passes. Es wird nur das aufgelistet, was abgespielt wird – Spannen, die auf 0–time.duration geschnitten wurden, eine Aufnahme, Gesichtszahl oder Sprecher, die in der Polsterung auf 0 gesetzt wurden, alles andere in der Polsterung weggelassen – sodass jedes t unverändert an POST …/overlays geht. Eine Layout- oder Audioanalyse, die nicht mehr zum Clip passt, wird weggelassen und in stale benannt. Mit der summary der Szene, welche Analysen available sind, und analyses. Gleiche Uhr wie die Clip-Analyse.

Anfrage

curl "$BASE/projects/123/clips/456/moments" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"clip_id": 456,
"time": { "clock": "viewer", "duration": 10.0, "...": "as in …/analysis" },
"summary": {
"description": "He grabs the rim and the crowd erupts",
"hook": "The dunk nobody saw coming",
"topic": "basketball",
"clip_type": "reaction",
"score": 8
},
"available": { "layout": true, "audio": true, "transcript": true, "video_moments": true },
"stale": [],
"analyses": { "...": "as in …/analysis" },
"moments": [
{ "t": 0.0, "kind": "beat", "source": "audio", "end": 10.0, "tempo_bpm": 120.0 },
{ "t": 0.0, "kind": "faces", "source": "layout", "count": 1 },
{ "t": 0.0, "kind": "shot", "source": "layout", "detail": "solo_talking_head" },
{ "t": 0.0, "kind": "speaker", "source": "transcript", "speaker": "speaker_0", "first_word": "Here" },
{ "t": 1.0, "kind": "moment", "source": "video", "end": 3.0, "detail": "action_peak",
"score": 8, "description": "Rim grab" },
{ "t": 3.0, "kind": "sound", "source": "transcript", "end": 4.0, "detail": "laughter" },
{ "t": 4.0, "kind": "cut", "source": "layout" },
{ "t": 4.0, "kind": "loud", "source": "audio", "end": 4.5, "over_db": 9.0 },
{ "t": 4.0, "kind": "shot", "source": "layout", "detail": "screen_share_with_webcam" }
]
}
GET/projects/{id}/analysis

Das gesamte Video, auf Videozeit: metadata, das transcript nach Segment mit Sprechern, sound_events, die video_moments des Vision-Passes und die talk_scenes des Transkript-Passes (jeweils mit einem …_status und einem …_pass-Block: Status und Modell des Passes, plus Fehler und Zeit des Vision-Passes), und jede Szene mit ihrem Hook, Score und degraded-Flag (true: der KI-Szenenschritt ist fehlgeschlagen und es ist ein unbewerteter Fallback fester Länge). include wählt Abschnitte aus; words (jedes Wort, mit Sprecher und Konfidenz) kommt nur, wenn benannt. analyses.transcription meldet eine erneute Transkription.

Anfrage

curl "$BASE/projects/123/analysis" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"time": { "clock": "video", "unit": "seconds", "note": "Seconds from the start of the upload." },
"analyses": {
"transcription": {
"status": null,
"...": "same fields as a clip's runs",
"rest": "POST /api/v1/projects/123/transcription",
"mcp": "transcribe_video"
}
},
"metadata": { "duration_sec": 693.5, "resolution": "1920x1080", "detected_orientation": "horizontal",
"...": "the rest of the upload's metadata" },
"transcript": {
"language": "english",
"provider": "openai_whisper",
"duration": 693.5,
"no_audio": false,
"speakers": [],
"segments": [{ "start": 99.0, "end": 106.0, "text": "Here we go.", "speaker": null }]
},
"sound_events": [{ "t": 103.0, "end": 104.0, "kind": "laughter", "label": "[laughter]",
"speaker": null, "confidence": null }],
"video_moments": [{ "start": 101.0, "end": 103.0, "type": "action_peak", "score": 8,
"description": "Rim grab" }],
"video_moments_status": "ok",
"video_moments_pass": { "status": "ok", "error": null, "model": "gemini-3.8-flash",
"analyzed_at": "2026-10-22T17:40:12+00:00" },
"talk_scenes": [{ "start": 95.0, "end": 105.0, "clip_type": "story", "score": 7,
"hook": "Why he almost quit", "topic": "basketball",
"description": "He tells how the season started", "confidence": 0.8 }],
"talk_scenes_status": "ok",
"talk_scenes_pass": { "status": "ok", "model": "gpt-4o-mini" },
"scenes": [{ "scene_id": 2265, "start": 100.0, "end": 110.0, "source": "merged",
"description": "He grabs the rim and the crowd erupts",
"hook": "The dunk nobody saw coming", "topic": "basketball",
"clip_type": "reaction", "score": 8, "degraded": false }]
}
POST/projects/{id}/clips/{clip_id}/audio-cues

Messe den Ton des Clips – laute Momente, leise Passagen, Beat und Tempo, Gesang – im Hintergrund. Frage GET …/analysis ab, bis analyses.audio_cues.status abgeschlossen oder fehlgeschlagen ist; das Ergebnis ist der audio-Abschnitt. Vorschlagen und Auto-Edit messen es selbst; rufe dies auf, um den Ton zuerst zu lesen. 409 audio_cues_running, audio_cues_current (die gespeicherte Messung stimmt noch mit der Datei des Clips überein) oder clip_file_missing. Bezahlt: ai_suggestions; keine Token; teilt sich ein Ratenlimit mit Effekten Vorschlagen und Auto-Edit.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/audio-cues" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"clip_id": 456,
"status": "running"
}

Bearbeitung

Alles, was der In-App-Editor tut, ist skriptfähig: Trimmen, Untertitel und deren Übersetzung, Layouts, Zooms, Bildschirm-Effekte, Geschwindigkeit, Emojis, GIFs, Sticker, Reaktionsclips, Soundeffekte, Logo, Fortschrittsbalken und Ausrichtung.

Zwei Zeitachsen. Overlays, die du hinzufügst (POST …/overlays) und jeder Vorschlag verwenden die Zeit des Betrachters – Sekunden vom Start des Clips, wie er abgespielt wird. Gespeicherte Einstellungen behalten die Zeiten relativ zur gepolsterten Clip-Datei, die an jedem Ende ein paar Sekunden länger ist; der Overlays-Endpunkt konvertiert für dich.

PUT/projects/{id}/scenes/{scene_id}/boundaries

Trimmen – verschiebt Start/Ende eines Clips. Alle Clips der Szene werden automatisch aktualisiert.

Anfrage

curl -X PUT "$BASE/projects/123/scenes/2265/boundaries" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"new_start_time": 12.0,
"new_end_time": 27.5
}

Antwort

{
"scene_id": 2265,
"project_id": 123,
"old_start_time": 0.0,
"old_end_time": 42.3,
"new_start_time": 12.0,
"new_end_time": 27.5,
"message": "Scene boundaries updated successfully."
}
GET · PUT/projects/{id}/clips/{clip_id}/settings

Den vollständigen Editor-Status lesen oder aktualisieren: Untertitel (mit secondary für eine zweite Zeile), Emojis, GIFs, Sticker und Reaktionsclips (gifs, unterschieden nach kind), SFX, Zoom, Bildschirm-Effekte, Framing, Logo, Fortschrittsbalken, Ausrichtung, speed und speedRanges. PUT ersetzt das gesamte Objekt – sende alles zurück, was GET zurückgegeben hat, mit deinen Änderungen; alles, was weggelassen wird, wird gelöscht.

Anfrage

curl -X PUT "$BASE/projects/123/clips/456/settings" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"orientation": "vertical",
"captions": {
"enabled": true,
"style": "hormozi",
"karaoke": true
},
"speed": 1.25
}

Antwort

{
"clip_id": 456,
"settings": {
"captions": { "enabled": true, "style": "hormozi", "karaoke": true },
"zoom": null,
"screenEffects": null,
"logo": null,
"progressBar": null,
"smartCrop": null,
"gifs": null,
"orientation": "vertical",
"speed": 1.25,
"speedRanges": null
}
}

Ein Zoom ist eine Form: {type: "zoom", start, end, scale, glide, target, center} – rein bei start (glide Sekunden, um dorthin zu gelangen, 0 springt), gehalten bei scale (1.05–2.5), zurück bei end, oder gehalten bis zum Ende des Clips, wenn end null ist. Ältere Punch- und Slow-Zooms werden konvertiert.

GET · PUT/projects/{id}/clips/{clip_id}/captions

Liest oder ersetzt Untertitelwörter mit Timing pro Wort.

Anfrage

curl -X PUT "$BASE/projects/123/clips/456/captions" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"words": [
{ "text": "Use", "start": 28.06, "end": 28.14 },
{ "text": "correct", "start": 28.14, "end": 28.22 }
]
}

Antwort

{
"words": [
{ "text": "Use", "start": 28.06, "end": 28.14, "highlight": null },
{ "text": "correct", "start": 28.14, "end": 28.22, "highlight": null }
]
}
PATCH/projects/{id}/clips/{clip_id}/name

Benennt einen Clip um. Ein leerer String setzt ihn auf den generierten Namen zurück.

Anfrage

curl -X PATCH "$BASE/projects/123/clips/456/name" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"name": "Best hook"
}

Antwort

{
"clip_id": 456,
"display_name": "Best hook"
}
POST/projects/{id}/clips/{clip_id}/transcribe

Die Audio dieses Clips erneut transkribieren und das Ergebnis als Untertitel verwenden. Ersetzt bearbeitete Wörter; antwortet mit den neuen Wörtern. Keine Tokens; ratenbegrenzt.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/transcribe" \
-H "Authorization: Bearer $KEY"
POST/projects/{id}/clips/{clip_id}/overlays

Overlays zur vom Betrachter gesehenen Zeit hinzufügen: emojis, inline_emojis, gifs, stickers, reaction_clips, sfx, zooms, screen_effects und speed_ranges. Die Zeitkonvertierung und Standardwerte des Editors werden für dich angewendet, und KI-Vorschläge können so gesendet werden, wie sie kamen. Es fügt nur hinzu.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/overlays" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"emojis": [{ "emoji": "🔥", "timestamp": 12.0 }],
"inline_emojis": [{ "emoji": "💰", "word_index": 5 }],
"gifs": [{ "source_id": "k1", "slug": "mind-blown", "mp4_url": "https://…",
"width": 480, "height": 270, "timestamp": 8.0 }],
"sfx": [{ "sfx_id": 3, "timestamp": 3.0, "volume": 0.4 }],
"zooms": [{ "start": 20.0, "length": 1.0, "scale": 1.3 }],
"screen_effects": [{ "look": "flash", "start": 20.0 }],
"speed_ranges": [{ "start": 31.0, "length": 2.5, "speed": 2.0 }]
}

Antwort

{
"clip_id": 456,
"settings": {
"emojis": [
{ "type": "floating", "emoji": "🔥", "timestamp": 14.0, "duration": 1.0,
"position": { "x": 0.5, "y": 0.694 }, "scale": 1.0 }
],
"zoom": [
{ "type": "zoom", "start": 22.0, "end": 23.0, "scale": 1.3, "glide": 0,
"target": "frame", "center": { "x": 0.5, "y": 0.5 } }
]
}
}

Ein Clip enthält bis zu 5 GIFs, 5 Sticker und 5 Reaktionsclips. spot auf einem Emoji oder Sticker folgt dem Hauptgesicht, und target: "face" bei einem Zoom zoomt darauf – kostenpflichtig (smart_crop), nach der Layout-Analyse des Clips.

GET · POST/projects/{id}/clips/{clip_id}/translations

Eine zweite Untertitelzeile in einer anderen Sprache. GET listet die Sprachen auf, die dieser Clip bereits hat, und die unterstützten; POST {"language": "es"} übersetzt ihn – 1 Token, kostenlos, wenn der Clip ihn bereits hat. Kostenpflichtig: caption_translation. Es wird angezeigt, sobald captions.secondary in den Einstellungen festgelegt ist.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/translations" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"language": "es"}'

Antwort

{
"project_id": 123,
"language": "es",
"lines": [{ "text": "Usa la palabra correcta", "start": 28.06, "end": 29.4 }],
"created": true,
"tokens_charged": 1
}
POST/projects/{id}/clips/{clip_id}/layout-analysis

Analysiere im Hintergrund, was jeder Moment des Clips zeigt – Shot-Typen, Gesichter, Bildschirm- und Webcam-Panels. Erforderlich, bevor Overlays einem Gesicht folgen können. Frage den Clip nach features.vision_analysis.layout_rerun_status ab, oder GET …/analysis nach analyses.layout.status; jeder Frame ist sein layout-Abschnitt. Kostenpflichtig: smart_crop; keine Token.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/layout-analysis" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"clip_id": 456,
"status": "running"
}
POST · DELETE/projects/{id}/clips/{clip_id}/logo

Ein Logo pro Clip hochladen (multipart, Feld file) oder entfernen. Ohne Browser mit POST /uploads/assets bereitstellen und unter …/logo/from-upload anhängen.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/logo/from-upload" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"asset_key": "originals/staging/42/9f1c2b7e.png"}'

KI-Vorschläge & Auto-Bearbeitung

Vorschläge sind schreibgeschützt: Sie geben Platzierungen zur Zeit des Betrachters zurück, bereit, an POST …/overlays gesendet zu werden, wie sie kamen. Kostenpflichtig: ai_suggestions. Keine Tokens; ratenbegrenzt.

POST/projects/{id}/clips/{clip_id}/{kind}/suggest

Vorschläge für einen Clip. kind ist gifs, stickers, reaction-clips, emojis, sfx, effects (Zoom- und Bildschirm-Effekt-Rezepte) oder speed (Stille beschleunigt, Zeitlupe). Query-Parameter max_suggestions.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/gifs/suggest?max_suggestions=3" \
-H "Authorization: Bearer $KEY"

Antwort

{
"clip_id": 456,
"suggestions": [
{
"source_id": "k1",
"slug": "mind-blown",
"title": "Mind Blown",
"mp4_url": "https://…",
"width": 480,
"height": 270,
"preview_url": "https://…",
"timestamp": 8.0,
"duration": 2.0,
"query": "mind blown",
"reason": "Reacts to the reveal"
}
]
}

effects und speed antworten mit audio_cues_ready: false, während das Audio des Clips noch gemessen wird – frage einige Sekunden später erneut. Ein Geschwindigkeitsvorschlag ist {start, end, speed}: sende ihn mit length = Ende − Start.

POST/projects/{id}/clips/{clip_id}/auto-edit

Plane im Hintergrund einen kompletten Schnitt für den Clip – Zooms, Bildschirm-Effekte, Sticker, Sounds und Geschwindigkeitsbereiche. Frage den Clip nach features.vision_analysis.auto_edit_rerun_status ab; der Schnitt ist features.vision_analysis.auto_edit ({effects, stickers, sfx, speed}, auch der auto_edit-Abschnitt von GET …/analysis). Nichts wird angewendet: Sende seine Teile an POST …/overlays. Kostenpflichtig: ai_suggestions; keine Token.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/auto-edit" \
-H "Authorization: Bearer $KEY"

Antwort

{
"project_id": 123,
"clip_id": 456,
"status": "running"
}

Export

POST/projects/{id}/clips/{clip_id}/export

Rendert einen Clip mit seinen gespeicherten Einstellungen. Liefert eine Export-ID zum Abfragen; kostet Tokens.

Anfrage

curl -X POST "$BASE/projects/123/clips/456/export" \
-H "Authorization: Bearer $KEY"

Antwort

{
"export_id": 37,
"status": "rendering",
"message": "Export render triggered"
}
GET/exports/{export_id}/status

Fragt einen Export ab. Wenn er fertig ist, ist download_url ein temporärer Link, der abläuft – lad die Datei zügig herunter.

Anfrage

curl "$BASE/exports/37/status" \
-H "Authorization: Bearer $KEY"

Antwort

{
"export_id": 37,
"status": "completed",
"download_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...&Expires=...",
"created_at": "2026-08-14T21:47:35Z",
"completed_at": "2026-08-14T21:48:42Z"
}
GET/exports

Listet deine Exporte, neueste zuerst. Filter: clip_id oder project_id. So lädst du einen Clip herunter: nimm den neuesten Export mit Status completed und lade seine download_url.

Anfrage

curl "$BASE/exports?clip_id=456" \
-H "Authorization: Bearer $KEY"

Antwort

{
"exports": [
{
"export_id": 37,
"clip_id": 456,
"project_id": 123,
"status": "completed",
"progress": null,
"export_number": 2,
"tokens_charged": 1,
"clip_duration_sec": 42.3,
"download_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...&Expires=...",
"created_at": "2026-08-14T21:47:35Z",
"completed_at": "2026-08-14T21:48:42Z"
}
],
"total": 2,
"limit": 20,
"offset": 0
}

Compilations

Eine Compilation ist ein Schnitt, der aus Clips all deiner Videos erstellt wird. Das Erstellen, Anordnen und Exportieren ist kostenpflichtig: compilation.

GET/compilations

Listet deine Compilations auf (projektübergreifende Clip-Sammlungen).

Anfrage

curl "$BASE/compilations" -H "Authorization: Bearer $KEY"

Antwort

{
"items": [
{
"id": 10,
"name": "Funny Personal Anecdotes",
"clip_count": 5,
"total_duration_sec": 149.9,
"output": { "width": 1920, "height": 1080, "fps": 30 },
"format": null,
"latest_export": null,
"created_at": "2026-08-10T19:05:41Z"
}
]
}
POST/compilations

Eine leere Compilation erstellen. Kostenpflichtig: compilation.

Anfrage

curl -X POST "$BASE/compilations" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"name": "Best of March",
"output": { "width": 1080, "height": 1920, "fps": 30 }
}
GET · PATCH/compilations/{id}

Eine Compilation lesen – ihre Clips, estimated_tokens für einen Export, den Schnittplan in arrangement_metadata.edit_plan und die Dateien, die sie in media abspielt – oder ihren name, output, logo_config oder progress_bar_config ändern.

Anfrage

curl "$BASE/compilations/10" -H "Authorization: Bearer $KEY"
GET/compilations/{id}/deletion-preview

Was beim Löschen mitgenommen würde: Uploads, die nur für diese Compilation existieren, und ausstehende Posts.

Anfrage

curl "$BASE/compilations/10/deletion-preview" -H "Authorization: Bearer $KEY"

Antwort

{
"compilation_id": 10,
"source_project_ids": [],
"scheduled_posts_pending": 0
}
DELETE/compilations/{id}

Eine Compilation löschen; ihre ausstehenden Posts werden storniert. delete_sources=true löscht auch die Uploads aus der Vorschau; übergebe sie als expected_project_ids und das Löschen wird (409) verweigert, wenn sich diese Menge geändert hat.

Anfrage

curl -X DELETE "$BASE/compilations/10" \
-H "Authorization: Bearer $KEY"

Antwort

{
"compilation_id": 10,
"deleted_project_ids": [],
"scheduled_posts_cancelled": 0
}
GET/compilations/available-clips

Deine Clips aus allen Videos, zum Hinzufügen. Abfrageparameter q, limit, offset.

Anfrage

curl "$BASE/compilations/available-clips?q=pivot&limit=50" \
-H "Authorization: Bearer $KEY"
POST · DELETE/compilations/{id}/clips

Fügt einen Clip hinzu (clip_id, optional position). DELETE /compilations/{id}/clips/{compilation_clip_id} entfernt einen.

Anfrage

curl -X POST "$BASE/compilations/10/clips" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"clip_id": 456}'
POST/compilations/{id}/clips/suggest

Weitere Clips aus deiner Bibliothek, die zu dieser Compilation passen, die besten zuerst.

Anfrage

curl -X POST "$BASE/compilations/10/clips/suggest" \
-H "Authorization: Bearer $KEY"
POST/compilations/suggest

Compilation-Ideen aus deiner Bibliothek für ein Briefing. Verwandle eine in eine Compilation mit POST /compilations/from-suggestion (name, clip_ids).

Anfrage

curl -X POST "$BASE/compilations/suggest" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "funny moments", "max_suggestions": 3}'

Antwort

{
"suggestions": [
{
"theme": "Funny moments",
"reason": "Five clips where the audience laughs",
"clip_ids": [456, 457, 461],
"total_duration_sec": 94.2
}
]
}
POST/compilations/{id}/export

Rendert die Compilation. Berechnet Tokens für die Quellsekunden, die sie abspielt (estimated_tokens auf der Compilation).

Anfrage

curl -X POST "$BASE/compilations/10/export" \
-H "Authorization: Bearer $KEY"

Antwort

{
"export_id": 5,
"compilation_id": 10,
"status": "pending",
"estimated_tokens": 3,
"message": "Export started"
}
GET/compilations/{id}/exports/{export_id}/status

Fragt einen Compilation-Export ab; download_url funktioniert wie bei einem Clip-Export. GET /compilations/{id}/exports listet sie auf.

Anfrage

curl "$BASE/compilations/10/exports/5/status" \
-H "Authorization: Bearer $KEY"

Antwort

{
"export_id": 5,
"compilation_id": 10,
"status": "completed",
"progress": null,
"download_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...&Expires=...",
"created_at": "2026-08-14T21:47:35Z",
"completed_at": "2026-08-14T21:50:02Z"
}

Compilation-Bearbeitung

Eine Compilation ist ein Schnittplan: Szenen mit ein bis drei Bereichen (ein Clip oder eine Datei) mit Übergängen und Textkarten, plus Overlays, Musik und einem Voiceover über den gesamten Schnitt. Zeiten sind Sekunden in die Compilation.

POST/compilations/{id}/arrange

Schneidet die Compilation mit KI in einen neuen Szenenplan um. format: custom (eine Montage; benötigt prompt), best_of, countdown, trailer, hook_loop, tutorial, qa_highlights oder auto. Ersetzt die Szenen und die daran angehefteten Emojis und GIFs; Untertitel, Musik und Erzählung bleiben erhalten.

Anfrage

curl -X POST "$BASE/compilations/10/arrange" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"format": "hook_loop"
}

Antwort

{
"id": 10,
"name": "Funny Personal Anecdotes",
"format": "hook_loop",
"total_duration_sec": 58.2,
"estimated_tokens": 1,
"clips": [
{ "compilation_clip_id": 88, "position": 0, "clip_id": 456, "duration_sec": 12.4, "missing": false }
],
"arrangement_metadata": {
"resolved_format": "hook_loop",
"degraded": false,
"edit_plan": {
"version": "2.0",
"scenes": [
{
"id": "1",
"layout": "full",
"sources": [
{ "clip_id": 456, "slot": 0, "audio": "primary",
"start_offset_sec": 3.0, "end_offset_sec": 9.5, "speed": 1.0 }
],
"text": []
}
]
}
}
}

degraded: true bedeutet, dass der KI-Schritt fehlgeschlagen ist und die Clips in der Reihenfolge beibehalten wurden.

POST/compilations/{id}/plan/undo · reset · place-added-clips

plan/undo geht zurück vor die letzte Anordnung, das Zurücksetzen oder Platzieren (wiederholt); plan/reset erstellt einen einfachen Schnitt, jeden Clip ganz; plan/place-added-clips arbeitet seit der KI-Bearbeitung hinzugefügte Clips ein. Kein Body.

Anfrage

curl -X POST "$BASE/compilations/10/plan/undo" \
-H "Authorization: Bearer $KEY"
POST/compilations/{id}/scenes/{scene_id}/regenerate

Schneidet eine Szene mit KI neu, den Rest belassend. Optional prompt. Szenen-IDs sind Text.

Anfrage

curl -X POST "$BASE/compilations/10/scenes/3/regenerate" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "use the boat clip instead"}'
PUT/compilations/{id}/scenes/{scene_id}/beat-pattern

Gibt einer Szene ein Beat-Muster: kurze stumme Wiederholungen ihres Clips auf den Beats der Musik, direkt davor. pattern: stutter, quick_stutter, build_up, jump_cut, teaser oder null zum Entfernen. Braucht gemessene Musik (bis dahin 409 music_not_measured).

Anfrage

curl -X PUT "$BASE/compilations/10/scenes/3/beat-pattern" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"pattern": "stutter"}'
PUT/compilations/{id}/plan

Ersetzt den Bearbeitungsplan. Layouts: full (1 Bereich), stack2 / cols2 / pip (2), stack3 / cols3 (3). Eine Quelle spielt eine clip_id oder einen media_key ab; ihre Offsets sind der Start und das Ende des Fensters in Sekunden in die Szene des Clips; höchstens eine Quelle pro Szene ist primary Audio. Übergänge: cut, fade, slide, wipe. Ausgelassene Overlays bleiben erhalten; ausgelassene music wird entfernt.

Anfrage

curl -X PUT "$BASE/compilations/10/plan" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"version": "2.0",
"scenes": [
{
"id": "1",
"layout": "full",
"sources": [{ "clip_id": 456, "audio": "primary",
"start_offset_sec": 2.0, "end_offset_sec": 14.5 }],
"text": [{ "text": "Day one", "role": "title", "start_ms": 0, "duration_ms": 2000 }]
},
{
"id": "2",
"layout": "stack2",
"transition_in": { "kind": "fade", "duration_ms": 400 },
"sources": [
{ "clip_id": 457, "slot": 0, "audio": "primary", "speed": 1.5 },
{ "clip_id": 458, "slot": 1 }
]
}
],
"music": { "track_id": "a1b2c3", "volume": 0.3 }
}
POST · PATCH/compilations/{id}/plan/overlays

POST fügt Emojis, GIFs, Sticker, Zooms, Bildschirm-Effekte und Soundeffekte über den gesamten Schnitt hinzu, in den Formen der Clip-Overlays. PATCH ersetzt stattdessen einen gespeicherten Satz vollständig (captions, emojis, gifs, screenEffects, zoom, sfx); nur das, was du sendest, ändert sich.

Anfrage

curl -X POST "$BASE/compilations/10/plan/overlays" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"emojis": [{ "emoji": "🎉", "timestamp": 3.0 }],
"screen_effects": [{ "look": "bw", "start": 10.0, "length": 2.0 }]
}

Antwort

{
"id": 10,
"arrangement_metadata": {
"edit_plan": {
"emojis": [
{ "type": "floating", "emoji": "🎉", "timestamp": 3.0, "duration": 1.0,
"position": { "x": 0.5, "y": 0.694 }, "scale": 1.0 }
]
}
}
}
POST/compilations/{id}/auto-edit

Bearbeitet die gesamte Compilation in einem Rutsch und wendet sie an, wobei nur das Leere gefüllt wird: wie jede Szene ankommt (jeder verfügbare Übergang), Textkarten (Wörter, Schriftart, Größe, Position, Timing), ein Bibliothekstrack, Geschwindigkeitsbereiche für Clips bei normaler Geschwindigkeit und der Fortschrittsbalken, plus Zooms, Bildschirm-Effekte, Sticker, GIFs, Emojis, Soundeffekte und bis zu 2 Reaktionsclip-Szenen. direction (optional, bis zu 300 Zeichen) steuert alles und wird für den nächsten Durchlauf beibehalten. Sende den zurückgegebenen take an …/auto-edit/undo, um ihn zu entfernen, oder hierher als replace_take, um ihn gegen einen neuen auszutauschen. Bezahlt: compilation; keine Token.

Anfrage

curl -X POST "$BASE/compilations/10/auto-edit" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"direction": "hype energy, big bold text"}'

Antwort

{
"compilation": { "id": 10, "...": "as GET /compilations/{id}" },
"take": {
"scene_ids": ["r1"],
"effect_ids": ["e1", "e2"],
"sticker_ids": ["g1"],
"emoji_ids": ["m1"],
"zoom_ids": ["z1"],
"sfx_ids": ["s1"],
"transitions": [{ "scene_id": "2", "kind": "slide", "duration_ms": 400 }],
"text_cards": [{ "scene_id": "1", "text": "Best of the year" }],
"music_track_id": "lib-42",
"speed_ranges": [{ "scene_id": "2", "slot": 0, "start": 24.0, "end": 25.2, "speed": 0.5 }],
"progress_bar": true
},
"counts": { "effects": 2, "stickers": 0, "gifs": 1, "emojis": 1,
"reaction_clips": 1, "zooms": 1, "sounds": 1, "transitions": 1,
"texts": 1, "music": 1, "speed_ranges": 1, "progress_bar": 1 }
}
GET/compilations/{id}/audio

Der gemessene Ton des Schnitts auf seiner eigenen Uhr: der Beat der Musik (oder eines hörbaren Clips), laute Momente, leise Strecken und Gesang; onsets=true fügt jeden Onset hinzu. Jeder Ton wird einmal im Hintergrund gemessen, wenn er zum ersten Mal gelesen wird oder in den Schnitt kommt — sources sagt, welche gemessen sind, und measuring bleibt true, bis alle es sind. Partylichter nehmen beat_first, beat_period und beat_clock daraus. Bezahlt: compilation; keine Token.

Anfrage

curl "$BASE/compilations/10/audio" \
-H "Authorization: Bearer $KEY"

Antwort

{
"compilation_id": 10,
"duration_sec": 37.4,
"measuring": false,
"sources": [
{ "kind": "music", "status": "measured", "track_id": "lib-42" },
{ "kind": "clip", "status": "measured", "scene_id": "1", "clip_id": 1621 }
],
"beat": [{ "start": 12.0, "end": 37.4, "first_beat": 12.02, "period": 0.38,
"tempo_bpm": 157.9, "clock": "edit" }],
"loud": [{ "t": 33.0, "end": 33.4, "over_db": 11.0 }],
"quiet": [{ "start": 3.4, "end": 9.0, "level_db": -38.0 }],
"singing": [],
"onsets": null
}
POST/compilations/{id}/media-scenes

Fügt eine Szene hinzu, die eine Datei anstelle eines Clips abspielt: einen Klipy-Reaktionsclip (klipy) oder ein hochgeladenes Video oder Bild (upload_key). Sie folgt auf after_scene_id oder ist die letzte; into_scene_id macht sie zu einem weiteren Bereich neben den Clips dieser Szene. Hochgeladenes Video zählt zu den Tokens des Exports; Reaktionsclips und Bilder sind kostenlos. Kostenpflichtig: compilation.

Anfrage

curl -X POST "$BASE/compilations/10/media-scenes" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"klipy": { "source_id": "c3", "slug": "emotional-damage",
"title": "Emotional Damage", "mp4_url": "https://…" },
"after_scene_id": "2"
}
POST · PATCH · DELETE/compilations/{id}/narration

Ein Voiceover über den gesamten Schnitt, für Untertitel transkribiert. POST lädt es hoch (Multipart, Feld file) oder hängt ein vorbereitetes unter …/narration/from-upload an; PATCH setzt volume und duck; DELETE entfernt es.

Anfrage

curl -X POST "$BASE/compilations/10/narration/from-upload" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"asset_key": "originals/staging/42/5d8e1a.mp3"}'

Antwort

{
"url": "https://clipmaster-media.s3.amazonaws.com/...mp3?...",
"volume": 1.0,
"duck": true,
"duration_sec": 61.4,
"word_count": 152
}
POST/compilations/{id}/music/suggest

Tracks, die zum Schnitt passen, jeder mit einem Grund. Wähle einen mit POST /music/tracks/{track_id}/select aus, dann setze music.track_id im Plan.

Anfrage

curl -X POST "$BASE/compilations/10/music/suggest" \
-H "Authorization: Bearer $KEY"
POST/compilations/{id}/{kind}/suggest

Vorschläge für den gesamten Schnitt, auf eigenen Sekunden: kind ist gifs, stickers oder emojis. Sende sie an POST …/plan/overlays. Kostenpflichtig: compilation.

Anfrage

curl -X POST "$BASE/compilations/10/emojis/suggest" \
-H "Authorization: Bearer $KEY"

Antwort

{
"compilation_id": 10,
"suggestions": [
{ "emoji": "😂", "timestamp": 14.2, "duration": 1.5, "reason": "The punchline lands" }
]
}
POST/compilations/{id}/scenes/{scene_id}/text/suggest

Titel- und Beschriftungszeilen für eine Szene.

Anfrage

curl -X POST "$BASE/compilations/10/scenes/1/text/suggest" \
-H "Authorization: Bearer $KEY"

Antwort

{
"suggestions": [
{ "text": "Day one", "role": "title" }
]
}

Planung

Veröffentliche Clips und Compilations auf einem verbundenen Kanal. Für die Planung brauchst du die Berechtigung für Social-Planung.

GET/social/accounts

Deine verbundenen Kanäle. Verbinde sie zuerst in der Web-App.

Anfrage

curl "$BASE/social/accounts" -H "Authorization: Bearer $KEY"

Antwort

{
"platforms_available": ["youtube"],
"accounts": [
{
"id": 2,
"platform": "youtube",
"account_name": "MyChannel",
"status": "active"
}
]
}
POST/scheduled-posts

Plant die Veröffentlichung eines Clip- oder Compilation-Exports. Idempotent – ein erneuter Versuch mit demselben Konto, Export und Zeitpunkt liefert den bestehenden Post.

Anfrage

curl -X POST "$BASE/scheduled-posts" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @body.json

Request-Body

{
"social_account_id": 2,
"clip_id": 456,
"export_id": 37,
"scheduled_at": "2026-08-20T16:00:00Z",
"title": "The pivot that saved us",
"hashtags": ["startup", "founder"],
"privacy": "public"
}

Antwort

{
"id": 12,
"clip_id": 456,
"export_id": 37,
"social_account_id": 2,
"platform": "youtube",
"account_name": "MyChannel",
"status": "scheduled",
"scheduled_at": "2026-08-20T16:00:00",
"title": "The pivot that saved us"
}
GET/scheduled-posts?from_date=&to_date=

Kalenderzeitraum mit geplanten und veröffentlichten Posts.

Anfrage

curl "$BASE/scheduled-posts?from_date=2026-08-01T00:00:00Z&to_date=2026-08-31T23:59:59Z" \
-H "Authorization: Bearer $KEY"

Antwort

{
"posts": [
{
"id": 12,
"status": "scheduled",
"scheduled_at": "2026-08-20T16:00:00",
"title": "The pivot that saved us"
}
]
}
PATCH · DELETE/scheduled-posts/{id}

Plant einen Beitrag neu oder bearbeitet ihn, bevor er veröffentlicht wird (scheduled_at, title, description, hashtags, privacy), oder bricht ihn ab.

Anfrage

curl -X PATCH "$BASE/scheduled-posts/12" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"scheduled_at": "2026-08-21T16:00:00Z"}'
POST/scheduled-posts/metadata-suggest

KI-Titel, -Beschreibung und -Hashtags aus dem Transkript eines Clips.

Anfrage

curl -X POST "$BASE/scheduled-posts/metadata-suggest" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"clip_id": 456, "platform": "youtube"}'

Antwort

{
"title": "The pivot that saved us",
"description": "How one decision turned the company around.",
"hashtags": ["startup", "founder"]
}
DELETE/social/accounts/{id}

Trennt einen Kanal. Seine Beitrags-Historie, ausstehende und veröffentlichte, geht damit verloren.

Anfrage

curl -X DELETE "$BASE/social/accounts/2" \
-H "Authorization: Bearer $KEY"

Mediathek

GET/export/styles

Listet die 15 Untertitelstile und ihre Standardwerte auf.

Anfrage

curl "$BASE/export/styles" \
-H "Authorization: Bearer $KEY"

Antwort

[
{
"key": "clean",
"name": "Clean",
"category": "social",
"fontFamily": "Inter",
"fontSize": 56,
"color": "#FFFFFF",
"highlightColor": "#9DC34F"
}
]
GET/sfx

Die Soundeffekt-Bibliothek; ihre IDs gehen in sfx-Overlays. Optional category.

Anfrage

curl "$BASE/sfx" -H "Authorization: Bearer $KEY"
GET/gifs/search · /gifs/trending

Suche Klipy, oder liste die Trends auf. kind ist gif, sticker oder clip (Reaktionsclips). Platziere ein Ergebnis mit id als source_id und mp4.url als mp4_url; ein Sticker benötigt auch image.url als image_url.

Anfrage

curl "$BASE/gifs/search?q=mind%20blown&kind=sticker&per_page=10" \
-H "Authorization: Bearer $KEY"

Antwort

{
"items": [
{
"id": "s9",
"slug": "mind-blown-sticker",
"title": "Mind Blown",
"kind": "sticker",
"mp4": { "url": "https://….webm", "width": 320, "height": 320 },
"preview": { "url": "https://….webp", "width": 160, "height": 160 },
"image": { "url": "https://….webp", "width": 320, "height": 320 }
}
],
"page": 1,
"per_page": 10,
"has_next": true
}
GET/music/search

Hintergrundmusik suchen. Optional genre, duration_min, duration_max.

Anfrage

curl "$BASE/music/search?q=upbeat" -H "Authorization: Bearer $KEY"
POST/music/tracks/{track_id}/select

Nimm einen Track in deine Bibliothek auf, damit eine Compilation ihn verwenden kann.

Anfrage

curl -X POST "$BASE/music/tracks/a1b2c3/select" \
-H "Authorization: Bearer $KEY"

Konto

GET/billing/balance

Dein Token-Guthaben: Gesamt, durch laufende Jobs reserviert und verfügbar.

Anfrage

curl "$BASE/billing/balance" -H "Authorization: Bearer $KEY"

Antwort

{
"balance": 120,
"reserved": 3,
"available": 117,
"total_purchased": 200,
"total_spent": 80
}
GET/billing/usage?period=30

Was du in den letzten period Tagen (1–365) verwendet hast.

Anfrage

curl "$BASE/billing/usage?period=30" -H "Authorization: Bearer $KEY"

Antwort

{
"period_days": 30,
"tokens_spent": 42,
"tokens_purchased": 0,
"uploads_count": 6,
"exports_count": 11,
"minutes_processed": 38.5,
"minutes_exported": 7.9
}

Fehler

Fehler enthalten einen maschinenlesbaren Code:

{
"detail": {
"error": "insufficient_tokens",
"message": "Not enough tokens for this operation"
}
}

Häufige Codes: api_access_required / session_auth_required (403), subscription_required (403, nennt die Plan-feature), insufficient_tokens (402), export_in_progress / export_expired (409). Ein ungültiger oder widerrufener Schlüssel gibt 401 zurück; bei Überschreitung eines Ratenlimits gibt 429 zurück.

Token-Kosten

Genau wie die App abgerechnet – 1 Token = 1 Quellminute für die Verarbeitung eines Uploads oder eines YouTube-Imports; Exporte werden nach den Regeln der App berechnet (eine Compilation nach den Quellsekunden, die sie abspielt); eine Clip-Untertitelübersetzung kostet 1 Token. Vorschläge, Auto-edit, Anordnung, Layout-Analyse, Audiomessung und erneute Transkription verbrauchen keine Token. Es gibt keine separate API-Abrechnung.