SimpliGen Docs
AI Agents

Control API-Referenz

Die lokale HTTP-API, die SimpliGen auf deinem Gerät bereitstellt, für die Erstellung benutzerdefinierter Integrationen und die Ausführung von Generierungen im Headless-Modus.

SimpliGen führt eine kleine HTTP Control API auf deinem Gerät aus, während die App offen ist. Es ist dieselbe API, mit der der MCP-Server kommuniziert, direkt verfügbar gemacht, sodass du SimpliGen von deinen eigenen Scripts, Services oder Agenten aus steuern kannst, auch mit der App minimiert in der Taskleiste.

MCP vs. Control API

Wenn du möchtest, dass ein KI-Agent (Claude, Codex usw.) SimpliGen nutzt, richte stattdessen den MCP-Server ein, der diese API umhüllt. Verwende die Control API direkt, wenn du eine benutzerdefinierte Integration in jeder beliebigen Sprache schreibst.

Basis-URL und Erkennung

Der Server bindet sich nur an Loopback und hat standardmäßig:

http://127.0.0.1:48199

Wenn dieser Port verwendet wird, nutzt SimpliGen einen vom Betriebssystem zugewiesenen Port. Der aktuelle Port (und die API-Version) wird immer in eine Erkennungsdatei 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 }

Lies diese Datei, um den aktiven Port zu finden, anstatt 48199 fest zu codieren.

Anforderungen

Die Control API läuft nur, wenn die App offen ist und die Maschine berechtigt ist, auf Agenten zuzugreifen (es ist Teil deiner Lizenz). Anfragen werden nur beantwortet, wenn der Host-Header ein Loopback-Alias ist, alles andere erhält 403 forbidden_host (ein DNS-Rebinding-Schutz).

Authentifizierung

Jeder Endpunkt außer GET /health benötigt ein Pairing-Token im Authorization-Header:

Authorization: Bearer sg-agent-xxxxxxxx...

Erstelle ein Token in der App unter Einstellungen → Agent verbinden (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 fehlender oder ungültiger Token gibt 401 unauthorized zurück.

Konventionen

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

Ein minimaler authentifizierter Aufruf:

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

Gesundheitsprüfung

GET /health

Liveness Probe. Keine Authentifizierung erforderlich.

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

Fähigkeiten

GET /capabilities

Listet jeden Preset auf, mit dem du generieren kannst, einen Eintrag pro (preset, mediaType), mit seinen Eingaben, Optionen, lokale 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 einen Cloud-Run (null wenn nicht berechtigt).
apiProviderNicht-null für externe API-Presets (z. B. OpenAI, Google), die die Control API nicht verteilen kann.
inputs / optionsWas der Preset akzeptiert und die Optionsbereiche/Seitenverhältnisse, die du an POST /generate übergeben kannst. steps/cfg sind nur nicht-null für Presets, die erweiterte Steuerelemente bereitstellen.
inputs.requiresPromptfalse für Presets, deren Anweisungen eingebaut sind (Ausschnitte, Kopf- oder Outfitwechsel, Upscales): ein leerer prompt ist gültig, und jeder von dir gesendete Text 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 läuft. Kein Body erforderlich.

{ "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. Daher Polling durchführen GET /status bis engineRunning wahr ist.

Das Starten einer bereits laufenden Engine 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 Multi-Gigabyte-Download und bleibt eine Aufgabe für die App, nicht für die API. Eine Maschine, auf der die Engine nicht ausgeführt werden kann, antwortet 409 engine_unsupported_hardware, ein erneutes Versuchen behebt dies nicht.

POST /engine/stop

Stoppt die lokale Engine und gibt ihren VRAM frei. Cloud-Generierungen sind nicht betroffen. Das Stoppen einer bereits heruntergefahrenen Engine ist ein Erfolg.

POST /engine/restart

Stoppt und startet es erneut, für eine fehlerhafte Engine oder nach einer benutzerdefinierten Node wurde installiert oder entfernt. Gleiches 202-Verhalten wie Start, wenn der Boot die Anfrage übersteigt.

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 (ansonsten 400 invalid_options).

Uploads

Eingaben (Quellbilder, Referenzbilder, Quellvideos) werden niemals als lokale Pfade übergeben. Lade die Bytes zuerst hoch und übergebe das zurückgegebene 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 Dateitypen geben 400 unsupported_file_type zurück.

Generieren

POST /generate

Reiht eine Generierung ein und gibt sofort einen jobId zurück. Polling durchführen GET /jobs/:id (siehe Jobs) für das Ergebnis.

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
presetIdjaVon GET /capabilities.
mediaTypeja"image" oder "video".
packIdneinFalls angegeben, muss dem Pack des Presets entsprechen.
promptbedingtErforderlich, wenn der Preset nicht inputs.requiresPrompt: false meldet. Diese Presets haben ihre Anweisungen eingebaut: Sende "", um sie unverändert auszuführen, oder füge Text hinzu, um zusätzliche Notizen zu übergeben.
backendnein"auto" (Standard), "local" oder "cloud". Auto bevorzugt lokal, wenn installiert, sonst Cloud, wenn 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 (Lip-Sync, Audio-zu-Video). Erforderlich, wenn der Preset acceptsAudio meldet, ansonsten wird der Job mit needs_audio abgelehnt.
audioStartSecondsneinWo in der Spur beginnen, in Sekunden. Auch unter options akzeptiert.
referenceVideosbedingtArray von Handles oder { handle, soundtrackMode, durationSeconds }, für Referenz-Clip-Presets.
referenceAudiosbedingtArray von Handles oder { handle, durationSeconds }, für Referenzsound-Presets.
lorasneinArray von { name, weight } zum Anwenden, für Presets, bei denen inputs.supportsLoras true ist. name entspricht einem LoRA-Anzeigenamen (oder Dateinamen) von GET /loras; weight verfällt auf die Standard-Stärke des LoRA. Unbekannte Namen geben 400 unknown_lora zurück. Nur lokales Backend für jetzt.
projectneinProjekt-id oder slug. Verfällt auf das aktive Projekt.
options.aspectRationeinMuss eines der unterstützten Seitenverhältnisse des Presets sein.
options.steps / options.cfgneinInnerhalb der beworbenen Bereiche des Presets.
options.negativePromptneinNegativer Prompt (der negative Wert der UI-Optionen des Advanced Options). Auch auf oberster Ebene als negativePrompt akzeptiert.
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 (bei denen apiProvider nicht-null ist, z. B. GPT Image 2, Veo) können hier nicht verteilt werden, du erhältst 400 unsupported_backend. Verwende einen lokalen oder SimpliGen Cloud Preset. Cloud erfordert ein verbundenes Konto (400 cloud_not_connected); lokal erfordert die installierten Modelle (400 preset_not_installed, bereite sie zuerst vor).

GET /loras

Listet die installierten LoRAs des Benutzers auf, damit Agenten entdecken können, was sie in das loras-Array von POST /generate eingeben sollen. Abgleich nach name (der Anzeigename).

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 }
  ]
}

Übergebe das LoRA, wo es zum Basis-Modell des Presets passt (baseModel), und verwende seine eigenen Trigger-Wörter in deinem Prompt, damit es aktiviert wird.

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 letzten Jobs als { "jobs": [ ...job... ] } zurück.

POST /jobs/:id/cancel

Bricht einen in die Warteschlange eingereihten/laufenden Job ab. Gibt { "jobId", "status", "note?" } zurück. Ein Cloud-Job, der bereits unterwegs ist, kann möglicherweise noch auf dem Server abgeschlossen werden (wird in note vermerkt).

Vorbereitung von Presets

Lokale Presets laden ihre Modelldateien beim ersten Gebrauch herunter. Du kannst 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": [ ... ] }. Polling durchführen, oder GET /capabilities (watch localReady), bis der Preset bereit ist.

Zeichen

Character Studio ist auch skriptbar. Zeichen sind nur lokal (Cloud wird abgelehnt). Siehe Characters für die Konzepte.

EndpunktZweck
GET /charactersZeichen auflisten.
GET /characters/:idEin Zeichen abrufen.
GET /character-presetsInstallierte Zeichen-Presets (Base, Edit, I2V).
GET /character-featuresVerfügbare Identitäts-/Erscheinungsmerkmalsoptionen.
POST /charactersErstelle ein Zeichen (mode: "generate" aus einer Beschreibung, oder "upload" aus einem hochgeladenen Basis-Image-Handle).
POST /characters/:id/generate-imageGeneriere ein Bild des Charakters ({ prompt, aspect?, count?, presetId? }).
POST /characters/:id/generate-frameGeneriere einen einzelnen Video-Start-Frame.
POST /characters/:id/animateAnimiere das Zeichen in ein Video.
POST /characters/:id/presetSetze den Standard-Preset des Charakters.
POST /characters/:id/enhanceSkaliere/verbessere ein Zeichen-Asset.

Alle Generierungs-Endpunkte geben einen jobId zurück, den du über GET /jobs/:id polisierst, genau wie POST /generate.

Rezepte

Verfasse Multi-Schritt-Rezepte (Flows) aus Packs und Presets. Entdecke die Bausteine, komponiere aus einer Spezifikation auf hoher Ebene, veröffentliche dann optional.

EndpunktZweck
GET /recipe-blocksEinstiegspunkte + jeder Preset verwendbar als Schritt, mit seinem Port-Vertrag.
POST /recipes/validateDry-run einer spec (Zusammensetzen+Validieren) oder einer config, kein Speichern. Gibt validation zurück.
POST /recipesKomponiere aus einer spec und speichere einen Entwurf. Gibt { recipeId, valid, errors, config } zurück.
GET /recipesListe jeden Rezept auf diesem Gerät (aus dem Store installiert oder hier verfasst) mit seinen inputs (Schlüssel, Art, Label, erforderlich, Optionen) und Schrittanzahl.
GET /recipes/:idHole ein Rezept, seine vollständige Config, seine inputs und readiness (pro Schritt: welcher Preset es läuft und ob es lokal installiert ist).
POST /recipes/:id/runFühre ein Rezept aus. Body: { inputs: { key: value }, engine?: "local" | "cloud" | "auto" }. Subject-Eingaben nehmen eine Charakter- oder Produkt-ID, Image/Video/Audio-Eingaben nehmen Upload-Handles, alles andere nimmt einfache Werte. Gibt { runId, status: "running", engine, steps, cloudCost? } zurück. Cloud-Runs werden im Voraus berechnet und zählen gegen die Ausgabenbegrenzung des Tokens.
GET /recipes/:id/runsAktuelle 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 Media-Schritt abgeschlossen ist.
POST /recipe-runs/:id/cancelStoppe einen Lauf. Keine weiteren Schritte starten; ein lokaler laufender Schritt wird unterbrochen.
POST /recipes/:id/publishSende zum Creator Marketplace (benötigt ein verbundenes Konto).

Produkte und Subjekte

Eine subject-Eingabe eines Rezepts nimmt entweder ein Zeichen oder ein Produkt. Produkte sind der andere Subjekttyp: ein benanntes Ding mit einem Basisfoto, verwendet von Product Studio und UGC-Rezepten.

EndpunktZweck
GET /subjectsJedes Subjekt, das ein Rezept nehmen kann: Zeichen und Produkte (id, type, name, status).
GET /productsProdukte auflisten.
GET /products/:idEin Produkt abrufen.
POST /productsErstelle ein Produkt aus einem hochgeladenen Foto: { name, image: <upload handle>, description?, category? }. Die Beschreibung und Kategorie werden in Rezept-Prompts eingewebt. Gibt { productId, product } zurück.
DELETE /products/:idEntferne ein Produkt und sein Foto.

Eine spec ist eine Beschreibung auf hoher Ebene; die App verbindet Ports automatisch, die Schritt-für-Schritt-Media-Kette und einen Prompt-Input 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" } }
}

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

Ausgabenbegrenzungen

Wenn ein Token eine Ausgabenbegrenzung hat, werden Cloud-Generierungen vor dem Versand berechnet und abgelehnt, wenn sie die verbleibende Zuteilung ü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 mit 503 cost_unknown fehl. Lokale Generierungen sind immer frei von Kreditkosten.

Ein vollständiger Flow

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_jsonBody ist kein gültiges JSON.
400invalid_optionsEin erforderliches Feld fehlt oder ist falsch formatiert.
400invalid_presetPreset/Pack/MediaType-Mismatch.
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 ausgewählt, aber Modelle sind nicht installiert.
400cloud_not_connectedCloud Backend ausgewählt, aber kein Konto verbunden.
401unauthorizedToken fehlt oder ungültig.
402exceeds_spend_capCloud-Kosten überschreiten die Ausgabenbegrenzung des Tokens.
403forbidden_hostNon-Loopback Host-Header.
404not_found / invalid_preset / job_not_foundUnbekannte Route, Preset oder Job.
413asset_too_largeUpload über 100 MB.
503cost_unknownBegrenztes Token; Cloud-Kosten konnten nicht bestimmt werden.
500internal_errorUnerwarteter Serverfehler.