SimpliGen Docs
AI Agents

Control API-Referenz

Die lokale HTTP-API, die SimpliGen auf Ihrer Maschine bereitstellt, zum Erstellen benutzerdefinierter Integrationen und zum Ausführen von Generierungen im Headless-Modus.

SimpliGen führt eine kleine HTTP Control API auf Ihrer Maschine aus, während die App offen ist. Es ist die gleiche API, mit der der MCP-Server spricht, direkt bereitgestellt, damit Sie SimpliGen von Ihren eigenen Skripten, Services oder Agenten aus steuern können, auch wenn die App auf das Tray minimiert ist.

MCP vs. Control API

Wenn Sie einfach nur möchten, dass ein KI-Agent (Claude, Codex, etc.) SimpliGen nutzt, richten Sie stattdessen den MCP-Server ein. Er umhüllt diese API. Nutzen Sie die Control API direkt, wenn Sie eine benutzerdefinierte Integration in einer beliebigen Sprache schreiben.

Basis-URL und Ermittlung

Der Server bindet sich an Loopback-Only und läuft standardmäßig auf:

http://127.0.0.1:48199

Wenn dieser Port belegt ist, greift SimpliGen auf einen vom Betriebssystem zugewiesenen Port zurück. Der aktuelle Port (und die API-Version) wird immer in eine Ermittlungsdatei im Benutzerverzeichnis der App geschrieben:

# Windows
%APPDATA%\simpligen\agent-api.json
# macOS
~/Library/Application Support/simpligen/agent-api.json
# Linux
~/.config/simpligen/agent-api.json
agent-api.json
{ "port": 48199, "version": 1 }

Lesen Sie diese Datei, um den aktiven Port zu ermitteln, anstatt 48199 hardcodiert zu verwenden.

Anforderungen

Die Control API wird nur ausgeführt, wenn die App offen ist und die Maschine zum Agent-Zugriff berechtigt ist (das ist Teil Ihrer Lizenz). Anfragen werden nur bearbeitet, wenn der Host-Header ein Loopback-Alias ist; alles andere erhält 403 forbidden_host (ein DNS-Rebinding-Schutz).

Authentifizierung

Jeder Endpoint außer GET /health erfordert ein Pairing-Token im Authorization-Header:

Authorization: Bearer sg-agent-xxxxxxxx...

Erstellen Sie ein Token in der App unter Settings → Connect an agent (siehe Agent verbinden). Das rohe Token wird einmal angezeigt; nur ein Hash wird gespeichert. Jedes Token kann eine optionale Ausgabenbegrenzung für Cloud-Generierungen haben. Das Widerrufen eines Tokens in der App wird sofort wirksam.

Ein fehlendes oder ungültiges Token gibt 401 unauthorized zurück.

Konventionen

  • Anfragen: JSON-Textkörper (Content-Type: application/json), bis zu 50 MB.
  • Antworten: immer JSON.
  • Fehler: Non-2xx-Antworten haben die Form { "errorCode": "...", "message": "..." }.
  • IDs: Presets werden durch presetId (+ optionales packId) adressiert; Jobs durch jobId.

Ein minimaler authentifizierter Aufruf:

TOKEN="sg-agent-..."
curl -s http://127.0.0.1:48199/status -H "Authorization: Bearer $TOKEN"

Gesundheit

GET /health

Liveness-Probe. Keine Authentifizierung erforderlich.

{ "ok": true, "name": "simpligen", "version": 1 }

Funktionen

GET /capabilities

Listet jeden Preset auf, mit dem Sie generieren können, einen Eintrag pro (preset, mediaType), mit seinen Eingaben, Optionen, lokaler Bereitschaft und Cloud-Berechtigung/Kosten.

{
  "capabilities": [
    {
      "packId": "local-core-pack",
      "presetId": "z-image-turbo",
      "mediaType": "image",
      "name": "Z-Image Turbo",
      "description": "Ultra-fast, high-quality images in seconds",
      "apiProvider": null,
      "inputs": {
        "acceptsPrompt": true,
        "requiresPrompt": true,
        "requiresImage": false,
        "acceptsReferenceImages": null,
        "acceptsVideo": false,
        "acceptsAudio": false,
        "acceptsReferenceVideos": false,
        "acceptsReferenceAudios": false,
        "supportsLoras": true
      },
      "options": {
        "steps": null,
        "cfg": null,
        "duration": null,
        "resolution": null,
        "aspectRatio": ["1:1", "3:4", "4:3", "9:16", "16:9"]
      },
      "cloudAliasTo": null,
      "localReady": true,
      "cloudEligible": true,
      "cloudCost": 4
    }
  ]
}
FeldBedeutung
localReadyAlle Modelldateien sind installiert; der Preset kann jetzt lokal ausgeführt werden.
cloudEligibleDer Preset kann auf SimpliGen Cloud ausgeführt werden.
cloudCostUngefähre Kreditkosten für eine Cloud-Ausführung (null, wenn nicht berechtigt).
apiProviderNicht null für externe API-Presets (z. B. OpenAI, Google), die die Control API nicht ausführen kann.
inputs / optionsWas der Preset akzeptiert und die Optionsbereiche/Seitenverhältnisse, die Sie an POST /generate übergeben können. steps/cfg sind nur dann nicht null, wenn der Preset erweiterte Steuerelemente verfügbar macht.
promptFamilyDie Prompt-Guide-Familie dieses Presets (zum Beispiel z-image), oder null, wenn keine angegeben ist. GET /prompt-guide/:presetId liefert den Guide.
inputs.requiresPromptfalse für Presets, deren Anweisungen eingebaut sind (Ausschnitte, Kopf- oder Outfits-Austausche, Hochskalierungen): Eine leere prompt ist gültig, und jeder Text, den Sie senden, wird als zusätzliche Notizen hinzugefügt.

Status

GET /status

{
  "engineRunning": true,
  "engineVersion": "v0.26.0",
  "cloudConnected": true,
  "creditBalance": 1280,
  "activeProject": { "id": "default", "name": "My Project" },
  "characters": { "enabled": true, "base": 1, "edit": 1, "i2v": 1, "enhancePresets": 2 }
}

POST /engine/start

Startet die lokale Engine, wenn sie nicht bereits ausgeführt wird. Benötigt keinen Body.

{ "engineRunning": true, "engineVersion": "v0.37.0", "engineStarting": false }

Ein Kaltstart dauert länger, als die Anfrage wartet. In diesem Fall ist die Antwort 202 mit engineStarting: true und die Engine startet weiter. Fragen Sie GET /status ab, bis engineRunning true ist.

Das Starten einer Engine, die bereits läuft, gibt 200 mit alreadyRunning: true zurück und ändert nichts. Wenn keine Engine installiert ist, ist die Antwort 409 engine_not_installed: Das Installieren einer ist ein mehrgigabyte-großer Download und bleibt eine Aufgabe für die App, nicht die API. Eine Maschine, auf der die Engine nicht läuft, antwortet mit 409 engine_unsupported_hardware, das Wiederholen wird das nicht beheben.

POST /engine/stop

Stoppt die lokale Engine und gibt ihr VRAM frei. Cloud-Generierung ist nicht betroffen. Das Stoppen einer Engine, die bereits heruntergefahren ist, ist ein Erfolg.

POST /engine/restart

Stoppt und startet sie erneut, für eine blockierte Engine oder nach der Installation oder dem Entfernen eines benutzerdefinierten Knotens. Das gleiche 202-Verhalten wie beim Start, wenn der Boot die Anfrage überschreitet.

Projekte

Projekte sind die Container, die Generierungen enthalten.

GET /projects

{ "projects": [ { "id": "default", "name": "My Project", "slug": "my-project" } ] }

POST /projects

Request
{ "name": "Campaign assets" }

Gibt 201 mit { "project": { ... } } zurück. name ist erforderlich (400 invalid_options ansonsten).

Uploads

Eingaben (Quellbilder, Referenzbilder, Quellvideos) werden nie als lokale Pfade übergeben. Laden Sie die Bytes zuerst hoch und übergeben Sie den zurückgegebenen Handle an POST /generate.

POST /uploads

Request
{ "filename": "ref.png", "dataBase64": "<base64 of the file bytes>" }
Response (201)
{ "handle": "a1b2c3d4.png", "sizeBytes": 51234 }

Max-Upload ist 100 MB (413 asset_too_large). Nicht unterstützte Erweiterungen geben 400 unsupported_file_type zurück.

Generieren

POST /generate

Reiht eine Generierung ein und gibt sofort jobId zurück. Fragen Sie GET /jobs/:id ab (siehe Jobs) um das Ergebnis zu erhalten.

Request
{
  "presetId": "z-image-turbo",
  "packId": "local-core-pack",
  "mediaType": "image",
  "prompt": "a red fox in the snow, cinematic",
  "backend": "auto",
  "project": "default",
  "image": "a1b2c3d4.png",
  "referenceImages": [{ "handle": "e5f6.png", "label": "style" }],
  "loras": [
    { "name": "RoomLora", "weight": 0.85 },
    { "name": "Mia", "weight": 0.75 }
  ],
  "options": { "aspectRatio": "16:9", "steps": 8, "negativePrompt": "blurry, watermark" }
}
FeldErforderlichNotizen
presetIdjaAus GET /capabilities.
mediaTypeja"image" oder "video".
packIdneinFalls angegeben, muss es dem Pack des Presets entsprechen.
promptbedingtErforderlich, es sei denn, der Preset meldet inputs.requiresPrompt: false. Diese Presets haben ihre Anweisungen eingebaut: Senden Sie "", um sie unverändert auszuführen, oder fügen Sie Text hinzu, um zusätzliche Notizen zu übergeben.
backendnein"auto" (Standard), "local" oder "cloud". Auto bevorzugt lokal, falls installiert, ansonsten Cloud, falls verbunden.
imagebedingtUpload-Handle. Erforderlich für Image-to-X-Presets (inputs.requiresImage).
videobedingtUpload-Handle, für Video-Input-Presets.
referenceImagesbedingtArray von Handles oder { handle, label }, für Referenzbild-Presets.
audiobedingtUpload-Handle, für audio-gesteuerte Presets (Lippensynchronisation, Audio-zu-Video). Erforderlich, wenn der Preset acceptsAudio meldet, ansonsten wird der Job mit needs_audio abgelehnt.
audioStartSecondsneinWo im Track zu starten, in Sekunden. Auch unter options akzeptiert.
referenceVideosbedingtArray von Handles oder { handle, soundtrackMode, durationSeconds }, für Referenzclip-Presets.
referenceAudiosbedingtArray von Handles oder { handle, durationSeconds }, für Referenzton-Presets.
lorasneinArray von { name, weight } zum Anwenden, für Presets, bei denen inputs.supportsLoras true ist. name stimmt mit dem Anzeigenamen (oder Dateinamen) einer LoRA aus GET /loras überein; weight wird standardmäßig auf die Standardstärke der LoRA eingestellt. Unbekannte Namen geben 400 unknown_lora zurück. Für jetzt nur lokales Backend.
projectneinProjekt id oder slug. Wird standardmäßig auf das aktive Projekt eingestellt.
options.aspectRationeinMuss eines der unterstützten Verhältnisse des Presets sein.
options.steps / options.cfgneinInnerhalb der beworbenen Bereiche des Presets.
options.negativePromptneinZusätzliche negative Begriffe (der negative Prompt der erweiterten Optionen der Benutzeroberfläche). Auch auf oberster Ebene als negativePrompt akzeptiert. Additiv: Der Standard-Negativ-Prompt des Presets wird immer angewendet, und Ihre Begriffe werden danach angehängt (, ). Senden Sie nichts, um den Standard des Presets zu verwenden. Bei Läufen über SimpliGen Cloud werden zusätzliche Begriffe nicht gesendet, und der Standard-Negativ-Prompt des Presets wird unverändert verwendet.
options.durationSecondsneinVideodauer.
options.resolutionneinAuflösungs-Tier-Label.
Response (201)
{ "jobId": "gen_abc123", "backend": "local", "status": "queued" }

Für einen Cloud-Job enthält die Antwort auch "cloudCost": <credits>.

Backends

Externe API-Presets (wobei apiProvider nicht null ist, z. B. GPT Image 2, Veo) können hier nicht ausgeführt werden, Sie erhalten 400 unsupported_backend. Nutzen Sie einen lokalen oder SimpliGen Cloud-Preset. Cloud erfordert ein verbundenes Konto (400 cloud_not_connected); lokal erfordert, dass die Modelle installiert sind (400 preset_not_installed, bereiten Sie sie zuerst vor).

GET /loras

Listet die installierten LoRAs des Benutzers auf, damit Agenten ermitteln können, was in das loras-Array von POST /generate übergeben werden soll. Abgleich nach name (dem Anzeigenamen).

Response
{
  "loras": [
    { "name": "RoomLora", "filename": "RoomLora_000002400.safetensors", "baseModel": "flux", "triggerWords": "a room", "defaultStrength": 0.9 },
    { "name": "Mia", "filename": "mia_v2.safetensors", "baseModel": "flux", "triggerWords": "mia", "defaultStrength": 1.0 }
  ]
}

Übergeben Sie die LoRA, wo sie zum Basis-Modell des Presets passt (baseModel), und nutzen Sie seine eigenen Trigger-Wörter in Ihrem Prompt, damit sie aktiviert werden.

Prompt-Guides

GET /prompt-guide/:presetId

Liefert den Prompt-Guide für ein Preset: wie sein Modell einen Prompt liest, welche Struktur und Länge es bevorzugt, Formulierungen für Kamera und Bewegung, negative Prompts, wie Charaktere beschrieben werden, und ausgearbeitete Beispiele. Lesen Sie ihn, bevor Sie den prompt für POST /generate schreiben. Guides werden von SimpliGen bereitgestellt und zwischengespeichert, sodass sie auch offline funktionieren, mit der letzten Kopie jedes Guides, die zuvor geöffnet wurde.

Response (200)
{
  "presetId": "z-image-turbo",
  "family": "z-image",
  "familyName": "Z-Image",
  "version": 1,
  "generic": false,
  "text": "# Z-Image prompting guide ...

## Negative prompts in SimpliGen
...

## Notes for this preset

..."
}
FeldBedeutung
family / familyNameDie Guide-Familie, zu der das Preset gehört, und ihr Anzeigename (siehe promptFamily bei GET /capabilities).
versionDie Version des Guides dieser Familie.
generictrue, wenn es für dieses Preset keinen modellspezifischen Guide gibt. Der text sagt das dann deutlich und gibt nur allgemeine Hinweise.
textDer Familien-Guide in Markdown, gefolgt von einem Abschnitt ## Negative prompts in SimpliGen, den alle Guides teilen. Hat das Preset eigene Hinweise, wird ein Abschnitt ## Notes for this preset angehängt.
HTTPerrorCodeWann
404unknown_presetKein Preset mit dieser ID.
503guides_unavailableDie Guides konnten nicht geladen werden, und es gibt keine zwischengespeicherte Kopie: "Prompt guides could not be loaded. Check the internet connection and try again."

Jobs

GET /jobs/:id

{
  "job": {
    "jobId": "gen_abc123",
    "status": "completed",
    "backend": "local",
    "mediaType": "image",
    "presetId": "z-image-turbo",
    "projectId": "default",
    "resultUrl": "local-file:///C:/Users/you/.../output.png",
    "resultPath": "C:/Users/you/.../output.png",
    "errorMessage": null,
    "createdAt": "2026-06-25T20:00:00.000Z",
    "completedAt": "2026-06-25T20:00:08.000Z"
  }
}

status ist einer von queued, processing, completed, failed. Bei Erfolg ist resultPath der dekodierte lokale Dateipfad; bei Fehler erklärt errorMessage warum. Unbekannte ID gibt 404 job_not_found zurück.

GET /jobs

Gibt die 25 neuesten Jobs als { "jobs": [ ...job... ] } zurück.

POST /jobs/:id/cancel

Bricht einen eingereiht/laufenden Job ab. Gibt { "jobId", "status", "note?" } zurück. Ein Cloud-Job, der bereits im Flug ist, kann auf dem Server trotzdem abgeschlossen werden (in note vermerkt).

Presets vorbereiten

Lokale Presets laden ihre Modelldateien bei der ersten Verwendung herunter. Sie können sie im Voraus vorbereiten.

POST /presets/prepare

Request
{ "presetId": "z-image-turbo", "mediaType": "image" }

Gibt 200 { "status": "already_installed" } oder 202 { "status": "started" } zurück (Download läuft im Hintergrund).

GET /presets/prepare

Gibt laufende Downloads zurück: { "downloads": [ ... ] }. Fragen Sie dies ab, oder GET /capabilities (beobachten Sie localReady), bis der Preset bereit ist.

Charaktere

Character Studio ist ebenfalls skriptierbar. Charaktere sind nur lokal (Cloud wird abgelehnt). Siehe Characters für die Konzepte.

EndpointZweck
GET /charactersCharaktere auflisten.
GET /characters/:idEinen Charakter abrufen.
GET /character-presetsInstallierte Charakter-Presets (Basis/Bearbeitung/i2v).
GET /character-featuresVerfügbare Optionen für Identität/Erscheinungsmerkmale.
POST /charactersEinen Charakter erstellen (mode: "generate" aus einer Beschreibung, oder "upload" aus einem hochgeladenen Basis-Bild-Handle).
POST /characters/:id/generate-imageEin Bild des Charakters generieren ({ prompt, aspect?, count?, presetId? }).
POST /characters/:id/generate-frameEinen einzelnen Video-Startrahmen generieren.
POST /characters/:id/animateDen Charakter in ein Video animieren.
POST /characters/:id/presetDas Standard-Preset des Charakters festlegen.
POST /characters/:id/enhanceEin Charakter-Asset hochskalieren oder verbessern. Die Quelle wird mit genau einem von target: "base", jobId (eine frühere Generierung) oder handle (aus POST /uploads) angegeben. Optional: mediaType, presetId, scale, keepResolution, applyAsBase.

Alle Generierungs-Endpoints geben eine jobId zurück, die Sie genau wie POST /generate über GET /jobs/:id abrufen.

Rezepte

Verfassen Sie mehrstufige Rezepte (Abläufe) aus Packs und Presets. Ermitteln Sie die Bausteine, stellen Sie aus einer High-Level-Spezifikation zusammen und veröffentlichen Sie optional.

EndpointZweck
GET /recipe-blocksEinstiegspunkte + jeder als Schritt verwendbare Preset mit seinem Port-Vertrag.
POST /recipes/validateDry-Run einer spec (Zusammensetzung+Validierung) oder einer config, kein Speichern. Gibt validation zurück.
POST /recipesAus einer spec zusammensetzen und als Entwurf speichern. Gibt { recipeId, valid, errors, config } zurück.
GET /recipesJeden Rezept auf diesem Gerät auflisten (aus dem Store installiert oder hier verfasst) mit seinen inputs (Schlüssel, Art, Label, erforderlich, Optionen) und Schrittanzahl.
GET /recipes/:idEinen Rezept abrufen, seine vollständige Konfiguration, seine inputs und readiness (pro Schritt: welcher Preset läuft und ob er lokal installiert ist).
POST /recipes/:id/runEinen Rezept ausführen. Body: { inputs: { key: value }, engine?: "local" | "cloud" | "auto" }. Subject-Eingaben benötigen eine Charakter- oder Produkt-ID, Bild/Video/Audio-Eingaben benötigen Upload-Handles, alles andere benötigt schlichte Werte. Gibt { runId, status: "running", engine, steps, cloudCost? } zurück. Cloud-Läufe werden im Voraus bepreist und zählen gegen die Ausgabenbegrenzung des Tokens.
GET /recipes/:id/runsNeueste Läufe eines Rezepts, neueste zuerst.
GET /recipe-runs/:idStatus eines Laufs: status (läuft, abgeschlossen, fehlgeschlagen, abgebrochen), steps (jeder mit Status, Job-ID und Ergebnispfad) und resultPath, sobald der letzte Medienschritt abgeschlossen ist.
POST /recipe-runs/:id/cancelEinen Lauf stoppen. Keine weiteren Schritte starten; ein lokal laufender Schritt wird unterbrochen.
POST /recipes/:id/publishIm Creator Marketplace einreichen (erfordert ein verbundenes Konto).

Produkte und Subjects

Eine subject-Eingabe eines Rezepts akzeptiert entweder einen Charakter oder ein Produkt. Produkte sind der andere Subject-Typ: ein benanntes Element mit einem Basisfoto, das von Product Studio und UGC-Rezepten verwendet wird.

EndpointZweck
GET /subjectsJeden Subject, den ein Rezept annehmen kann: Charaktere und Produkte (id, type, name, status).
GET /productsProdukte auflisten.
GET /products/:idEin Produkt abrufen.
POST /productsEin Produkt aus einem hochgeladenen Foto erstellen: { name, image: <upload handle>, description?, category? }. Die Beschreibung und Kategorie werden in Rezept-Prompts verwoben. Gibt { productId, product } zurück.
DELETE /products/:idEin Produkt und sein Foto entfernen.

Eine spec ist eine High-Level-Beschreibung; die App verdrahtet Ports automatisch, die Schritt-zu-Schritt-Medienkette und eine Prompt-Eingabe pro Schritt, dann validiert.

POST /recipes request
{
  "spec": {
    "name": "Product to spinning video",
    "category": "product",
    "steps": [
      { "preset": "krea2-pack:krea2-turbo" },
      { "preset": "wan-2.2-video-pack:wan-2.2-i2v" }
    ]
  }
}
Response (201)
{
  "recipeId": "b1f2…",
  "valid": true,
  "errors": [],
  "config": { "blocks": [ "…" ], "inputs": [ "…" ], "output": { "from": "n2.video" } }
}

Das Zusammensetzen und Speichern benötigt kein Creator-Konto. POST /recipes/:id/publish erfordert ein verbundenes Konto und gibt not_connected zurück (mit needsConnect: true), bis der Benutzer eines in der App verbindet; der gleiche Entwurf wird dann unverändert veröffentlicht. Jeder Preset, den das Rezept verwendet, muss zu einem verteilbaren First-Party-Pack gehören.

Video Studio

Filme sind Video Studio-Dokumente: Clips (zu rendernde Aufnahmen) auf einer Zeitleiste über Audio-Spuren. Jede Bearbeitungsroute antwortet { change, timeline }: Was geändert wurde und die Zeitleiste des Films danach (die gleiche Form, die GET /films/:id antwortet). Mit dem Film, der im Studio offen ist, wird die Änderung live angezeigt und mit Strg+Z rückgängig gemacht; ein geschlossener Film wird bearbeitet und gespeichert.

Clips werden im Pfad nach ID, Name oder Nummer benannt (ihre Reihenfolge auf der Zeitleiste, am frühesten zuerst). Zeiten sind Sekunden, oder Takte, sobald der Film ein Tempo hat: eine Position ist 3, { "seconds": 3 } oder { "bar": 5 } (Takt 1 ist der erste Downbeat), eine Länge ist 5, { "seconds": 5 } oder { "bars": 2 }.

RouteWas es tut
GET /films?projectId=Filme eines Projekts (Standard: das aktuelle).
POST /filmsEinen Film erstellen: name, optional projectId, aspect (16:9, 9:16, 1:1), quality (480p, 720p, 1080p), renderOn (local, cloud), presets ({ t2v, i2v, r2v }). Antwortet mit der Zeitleiste.
GET /films/:idDie Zeitleiste.
PATCH /films/:idFilm-Einstellungen: aspect, quality, hires2x, renderOn, presets, subject, cast (Namen oder IDs), location (Name, ID oder null).
POST /films/:id/tracksEine Spur hinzufügen: upload (ein Handle aus POST /uploads), kind (singing, music, dialogue, effects), name, at.
PATCH /films/:id/tracks/:trackat, muted, volume (0 bis 1).
POST /films/:id/tempoDas Tempo aus der längsten nicht stummgeschalteten Spur ermitteln, oder aus track. Antwortet { bpm, offset, track, timeline }.
POST /films/:id/clipsEinen Clip hinzufügen: at, length, name, lane.
PATCH /films/:id/clips/:clipshots (jeweils { prompt, seconds, line, speaker, framing }), cast, location ("none" verwirft den Ort des Films, "film" übernimmt ihn wieder), link (fresh, continue, motion; none und frame werden auch akzeptiert, als fresh und continue), hears ([{ track, on }]), preset.
POST /films/:id/clips/:clip/moveat, lane.
POST /films/:id/clips/:clip/trimlength, trimIn (wo der Clip in seinem Take beginnt; 0 ist der Anfang des Takes).
DELETE /films/:id/clips/:clipDen Clip entfernen.
POST /films/:id/planEinen Entwurf verfassen (siehe unten).
POST /films/:id/fadestarget (ein Clip oder eine Spur), fadeIn, fadeOut.
POST /films/:id/markersat, name.
POST /films/:id/export-rangefrom und to (beide erforderlich), oder clear: true.
POST /films/:id/rendersClips rendern ("stale", Standard, oder eine Liste). Antwortet sofort 202 mit { started, held, credits }, oder 200 mit einer note, wenn nichts gerendert werden muss.
GET /films/:id/clips/:clip/takesDie Takes des Clips, neueste zuerst.
POST /films/:id/clips/:clip/takegenerationId: Diesen Take zu dem Take machen, den der Clip zeigt.
POST /films/:id/exportDen Film zusammennähen. Antwortet 201 mit { path, resultUrl, blanks }.

Einen Entwurf verfassen

POST /films/:id/plan
{
  "mode": "append",
  "cast": ["Kai", "Mira"],
  "location": "Rooftop",
  "clips": [
    { "bars": 2, "shots": [{ "prompt": "@Kai looks over the city", "framing": "wide" }] },
    { "bars": 2, "link": "continue",
      "shots": [{ "prompt": "@Kai sings to camera", "line": "Neon rain", "speaker": "Kai", "framing": "close-up" }] },
    { "bars": 3, "location": "Neon Street", "cast": ["Mira"],
      "shots": [{ "prompt": "@Mira walks through the rain", "seconds": 4 }, { "prompt": "she turns", "seconds": 3 }] }
  ]
}

Der Entwurf wird zuerst als Ganzes überprüft. Ein Entwurf mit Problemen antwortet 400 invalid_plan mit jedem Problem in details.problems (jeweils mit seinem Clip vorangestellt, z. B. clip 2: ...) und ändert nichts. mode: "replace" ersetzt jeden Clip und wird abgelehnt, wenn Clips Takes haben, es sei denn "discardTakes": true.

Renders und Ausgabenbegrenzung

Ein Cloud-Render wird im Voraus bepreist und zählt gegen die Ausgabenbegrenzung des Tokens: über der Begrenzung antwortet 402 exceeds_spend_cap, ein unbekannter Preis 503 cost_unknown. Clips, die vom Clip davor fortgesetzt werden, rendern einzeln, jeder nach dem Take, an den er anschließt; der Aufruf antwortet sofort, und GET /films/:id zeigt die take jedes Clips: none, rendering, current, edited, longer, unknown (es kann noch nicht gesagt werden) oder imported (ein importiertes Video, das nie gerendert wurde).

Orte

RouteWas es tut
GET /locationsDie Orte der Bibliothek: id, name, description, hasPicture.
POST /locationsEinen Ort aus seinem Bild erstellen: name, description und upload (ein Handle) oder fromJob (ein fertiggestellter Image-Job).

Ausgabenbegrenzungen

Wenn ein Token eine Ausgabenbegrenzung hat, werden Cloud-Generierungen vor dem Versand bepreist und abgelehnt, wenn sie die verbleibende Zulage überschreiten würden (402 exceeds_spend_cap). Wenn die Kosten nicht bestimmt werden können (Cloud-Status nicht verfügbar), schlägt ein begrenztes Token geschlossen mit 503 cost_unknown fehl. Lokale Generierungen sind immer kostenlos.

Ein kompletter Ablauf

BASE=http://127.0.0.1:48199
AUTH="Authorization: Bearer sg-agent-..."

# 1. Pick a ready preset
curl -s $BASE/capabilities -H "$AUTH"

# 2. Generate
JOB=$(curl -s $BASE/generate -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{"presetId":"z-image-turbo","mediaType":"image","prompt":"a red fox in the snow","options":{"aspectRatio":"16:9"}}' \
  | jq -r .jobId)

# 3. Poll until done, then read resultPath
curl -s $BASE/jobs/$JOB -H "$AUTH" | jq '.job | {status, resultPath, errorMessage}'

Fehlercodes

HTTPerrorCodeWann
400invalid_jsonDer Textkörper ist kein gültiges JSON.
400invalid_optionsEin erforderliches Feld fehlt oder ist malformed.
400invalid_presetPreset/Pack/mediaType stimmen nicht überein.
400needs_*Eine erforderliche Eingabe (Prompt, Bild, Referenzen) fehlt.
400invalid_handleEine Eingabe war kein gültiges Upload-Handle.
400unsupported_backendPreset läuft auf einer externen API.
400preset_not_installedLokales Backend gewählt, aber Modelle sind nicht installiert.
400cloud_not_connectedCloud-Backend gewählt, aber kein verbundenes Konto.
400invalid_planEin Film-Entwurf hat Probleme; details.problems listet sie alle auf.
400no_tempoEine Zeit in Takten, bevor der Film ein Tempo hat; ermitteln Sie zuerst das Tempo.
400no_audioTempo, das von einem Film ohne Audio-Spur verlangt wird.
400no_pulseEs konnte kein konstanter Beat in der Spur gehört werden.
401unauthorizedFehlendes oder ungültiges Token.
402exceeds_spend_capCloud-Kosten überschreiten die Ausgabenbegrenzung des Tokens.
402exceeds_balanceDas Cloud-Guthaben deckt die Render nicht ab.
403forbidden_hostNon-Loopback Host-Header.
403studio_not_installedDas Video Studio ist nicht auf diesem Computer installiert.
404not_found / invalid_preset / job_not_foundUnbekannte Route, Preset oder Job.
404unknown_presetGET /prompt-guide/:presetId mit einer ID, die kein Preset ist.
404film_not_foundKein Film mit dieser ID.
404clip_not_foundKein Clip nach dieser ID, Name oder Nummer.
404track_not_foundKeine Spur nach diesem Namen oder dieser ID.
404cast_not_foundKein Charakter dieses Namens oder dieser ID in der Bibliothek.
404location_not_foundKein Ort dieses Namens oder dieser ID, oder er hat noch kein Bild.
409clips_not_readyExport, während Clips noch einen Render benötigen; details.clips nennt sie.
413asset_too_largeUpload über 100 MB.
503guides_unavailableDie Prompt-Guides konnten nicht geladen werden, und keine sind zwischengespeichert.
503cost_unknownBegrenztes Token; Cloud-Kosten konnten nicht bestimmt werden.
503studio_busyDas SimpliGen-Fenster konnte nicht erreicht werden oder antwortete nicht rechtzeitig. Falls zeitüberschritten, wurde die Änderung möglicherweise trotzdem vorgenommen: Lesen Sie den Film, bevor Sie es erneut versuchen.
500internal_errorUnerwarteter Serverfehler.