SimpliGen Docs
AI Agents

Référence de l'API Control

L'API HTTP locale que SimpliGen expose sur votre machine, pour construire des intégrations personnalisées et exécuter des générations en mode headless.

SimpliGen exécute une petite API Control HTTP sur votre machine tandis que l'application est ouverte. C'est la même API avec laquelle le serveur MCP communique, exposée directement pour que vous puissiez piloter SimpliGen à partir de vos propres scripts, services ou agents, y compris avec l'application minimisée dans la barre d'état.

MCP vs l'API Control

Si vous voulez simplement qu'un agent IA (Claude, Codex, etc.) utilise SimpliGen, configurez le serveur MCP à la place ; il encapsule cette API. Utilisez l'API Control directement quand vous écrivez une intégration personnalisée dans n'importe quel langage.

URL de base et découverte

Le serveur se lie à loopback uniquement et par défaut à :

http://127.0.0.1:48199

Si ce port est occupé, SimpliGen bascule sur un port attribué par le système d'exploitation. Le port actuel (et la version de l'API) est toujours écrit dans un fichier de découverte du répertoire de données utilisateur de l'application :

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

Lisez ce fichier pour trouver le port en direct plutôt que de coder en dur 48199.

Conditions

L'API Control ne s'exécute que quand l'application est ouverte et que la machine est autorisée à accéder aux agents (cela fait partie de votre licence). Les demandes ne sont servies que quand l'en-tête Host est un alias loopback ; tout le reste reçoit 403 forbidden_host (une protection contre le rebond DNS).

Authentification

Tous les points de terminaison sauf GET /health nécessitent un jeton d'appairage dans l'en-tête Authorization :

Authorization: Bearer sg-agent-xxxxxxxx...

Créez un jeton dans l'application sous Paramètres → Connecter un agent (voir Connecter un agent). Le jeton brut s'affiche une seule fois ; seul un hash est stocké. Chaque jeton peut avoir un plafond de dépenses optionnel pour les générations cloud. Révoquer un jeton dans l'application prend effet immédiatement.

Un jeton manquant ou invalide retourne 401 unauthorized.

Conventions

  • Requêtes : corps JSON (Content-Type: application/json), jusqu'à 50 MB.
  • Réponses : toujours JSON.
  • Erreurs : les réponses non-2xx ont la forme { "errorCode": "...", "message": "..." }.
  • IDs : les présélections sont adressées par presetId (+ packId optionnel) ; les tâches par jobId.

Un appel authentifié minimal :

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

Santé

GET /health

Sonde de vivacité. Pas d'authentification.

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

Capacités

GET /capabilities

Liste chaque présélection avec laquelle vous pouvez générer, une entrée par (preset, mediaType), avec ses entrées, options, disponibilité locale et admissibilité/coût cloud.

{
  "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
    }
  ]
}
ChampSignification
localReadyTous les fichiers du modèle sont installés ; la présélection peut s'exécuter localement maintenant.
cloudEligibleLa présélection peut s'exécuter sur SimpliGen Cloud.
cloudCostCoût de crédit approximatif pour une exécution cloud (null si non admissible).
apiProviderNon-null pour les présélections d'API externes (p. ex. OpenAI, Google) que l'API Control ne peut pas expédier.
inputs / optionsCe que la présélection accepte et les plages d'options/rapports d'aspect que vous pouvez passer à POST /generate. steps/cfg sont non-null uniquement pour les présélections qui exposent des contrôles avancés.
promptFamilyLa famille de guide d'invite pour cette présélection (par exemple z-image), ou null si aucune n'est déclarée. GET /prompt-guide/:presetId retourne le guide.
inputs.requiresPromptfalse pour les présélections dont les instructions sont intégrées (découpes, échanges de tête ou d'ensemble, surélévations) : une prompt vide est valide, et tout texte que vous envoyez est ajouté comme notes supplémentaires.

Statut

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

Démarre le moteur local quand il ne s'exécute pas déjà. N'accepte pas de corps.

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

Un démarrage à froid prend plus de temps que celui que la requête attend. Quand cela se produit, la réponse est 202 avec engineStarting: true et le moteur continue de démarrer, alors interrogez GET /status jusqu'à ce que engineRunning soit true.

Le démarrage d'un moteur qui s'exécute déjà retourne 200 avec alreadyRunning: true et ne change rien. Si aucun moteur n'est installé, la réponse est 409 engine_not_installed : l'installation d'un moteur est un téléchargement de plusieurs gigaoctets et reste une tâche pour l'application, pas pour l'API. Une machine que le moteur refuse d'exécuter répond 409 engine_unsupported_hardware, et réessayer ne le résoudra pas.

POST /engine/stop

Arrête le moteur local et libère sa VRAM. La génération cloud n'est pas affectée. Arrêter un moteur qui est déjà arrêté est un succès.

POST /engine/restart

L'arrête et le relance, pour un moteur bloqué ou après qu'un nœud personnalisé ait été installé ou supprimé. Le même comportement 202 que start quand le démarrage dépasse la requête.

Projets

Les projets sont les conteneurs qui contiennent les générations.

GET /projects

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

POST /projects

Request
{ "name": "Campaign assets" }

Retourne 201 avec { "project": { ... } }. name est obligatoire (sinon 400 invalid_options).

Téléchargements

Les entrées (images source, images de référence, vidéos source) ne sont jamais passées comme chemins locaux. Téléchargez d'abord les octets et passez la poignée retournée à POST /generate.

POST /uploads

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

Le téléchargement maximal est 100 MB (413 asset_too_large). Les extensions non supportées retournent 400 unsupported_file_type.

Générer

POST /generate

Met une génération en file d'attente et retourne immédiatement avec un jobId. Interrogez GET /jobs/:id (voir Jobs) pour le résultat.

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" }
}
ChampObligatoireNotes
presetIdouiDe GET /capabilities.
mediaTypeoui"image" ou "video".
packIdnonS'il est donné, doit correspondre au pack de la présélection.
promptconditionnelObligatoire sauf si la présélection rapporte inputs.requiresPrompt: false. Ces présélections ont leurs instructions intégrées : envoyez "" pour les exécuter telles qu'elles sont, ou ajoutez du texte pour passer des notes supplémentaires.
backendnon"auto" (par défaut), "local", ou "cloud". Auto préfère local s'il est installé, sinon cloud s'il est connecté.
imageconditionnelPoignée de téléchargement. Obligatoire pour les présélections image-vers-X (inputs.requiresImage).
videoconditionnelPoignée de téléchargement, pour les présélections d'entrée vidéo.
referenceImagesconditionnelTableau de poignées ou { handle, label }, pour les présélections d'images de référence.
audioconditionnelPoignée de téléchargement, pour les présélections pilotées par l'audio (synchronisation labiale, audio vers vidéo). Obligatoire quand la présélection rapporte acceptsAudio, sinon la tâche est rejetée avec needs_audio.
audioStartSecondsnonOù dans la piste commencer, en secondes. Aussi accepté sous options.
referenceVideosconditionnelTableau de poignées ou { handle, soundtrackMode, durationSeconds }, pour les présélections de clips de référence.
referenceAudiosconditionnelTableau de poignées ou { handle, durationSeconds }, pour les présélections de sons de référence.
lorasnonTableau de { name, weight } à appliquer, pour les présélections où inputs.supportsLoras est true. name correspond au nom d'affichage d'une LoRA (ou au nom de fichier) de GET /loras ; weight par défaut à la force par défaut de la LoRA. Les noms inconnus retournent 400 unknown_lora. Backend local uniquement pour l'instant.
projectnonProjet id ou slug. Par défaut au projet actif.
options.aspectRationonDoit être l'un des rapports supportés de la présélection.
options.steps / options.cfgnonDans les plages annoncées de la présélection.
options.negativePromptnonTermes négatifs supplémentaires (le négatif des Options avancées de l'interface). Aussi accepté au niveau supérieur comme negativePrompt. Additif : le négatif par défaut de la présélection est toujours appliqué et vos termes sont ajoutés après (, ). N'envoyez rien pour utiliser le négatif par défaut de la présélection. Sur les exécutions SimpliGen Cloud, les termes supplémentaires ne sont pas envoyés, et le négatif par défaut de la présélection est utilisé tel quel.
options.durationSecondsnonDurée de la vidéo.
options.resolutionnonLabel de niveau de résolution.
Response (201)
{ "jobId": "gen_abc123", "backend": "local", "status": "queued" }

Pour une tâche cloud, la réponse inclut aussi "cloudCost": <credits>.

Backends

Les présélections d'API externes (où apiProvider est non-null, p. ex. GPT Image 2, Veo) ne peuvent pas être expédiées ici, vous obtiendrez 400 unsupported_backend. Utilisez une présélection locale ou SimpliGen Cloud. Cloud nécessite un compte connecté (400 cloud_not_connected) ; local nécessite les modèles installés (400 preset_not_installed, préparez-les d'abord).

GET /loras

Liste les LoRAs installées de l'utilisateur pour que les agents découvrent quoi passer dans le tableau loras de POST /generate. Faites correspondre sur name (le nom d'affichage).

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

Passez la LoRA où elle correspond au modèle de base de la présélection (baseModel), et utilisez ses propres mots déclencheurs dans votre invite pour qu'elle s'active.

Guides d'invite

GET /prompt-guide/:presetId

Retourne le guide d'invite pour une présélection : comment son modèle lit une invite, la structure et la longueur qu'il aime, la terminologie caméra et mouvement, les négatifs, comment formuler les caractères, et des exemples fonctionnels. Lisez-le avant d'écrire la prompt pour POST /generate. Les guides sont servis par SimpliGen et mis en cache, ils fonctionnent aussi hors ligne à partir de la dernière copie de chaque guide qui a été ouvert avant.

Response (200)
{
  "presetId": "z-image-turbo",
  "family": "z-image",
  "familyName": "Z-Image",
  "version": 1,
  "generic": false,
  "text": "# Z-Image prompting guide ...\n\n## Negative prompts in SimpliGen\n...\n\n## Notes for this preset\n\n..."
}
ChampSignification
family / familyNameLa famille de guide à laquelle la présélection se résout, et son nom d'affichage (voir promptFamily sur GET /capabilities).
versionLa version du guide de cette famille.
generictrue quand aucun guide spécifique au modèle n'existe pour cette présélection. Le text le dit alors clairement et donne seulement des conseils généraux.
textLe guide de famille en Markdown, suivi d'une section ## Negative prompts in SimpliGen que chaque guide partage. Quand la présélection a ses propres notes, une section ## Notes for this preset est ajoutée.
HTTPerrorCodeQuand
404unknown_presetPas de présélection avec cet id.
503guides_unavailableLes guides n'ont pas pu être chargés et aucune copie mise en cache n'existe : « Les guides d'invite n'ont pas pu être chargés. Vérifiez la connexion Internet et réessayez. »

Tâches

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 est l'un de queued, processing, completed, failed. En cas de succès, resultPath est le chemin du fichier local décodé ; en cas d'échec, errorMessage explique pourquoi. Un id inconnu retourne 404 job_not_found.

GET /jobs

Retourne les 25 tâches les plus récentes comme { "jobs": [ ...job... ] }.

POST /jobs/:id/cancel

Annule une tâche en file d'attente ou en cours. Retourne { "jobId", "status", "note?" }. Une tâche cloud déjà en vol peut quand même se terminer sur le serveur (noté dans note).

Préparer les présélections

Les présélections locales téléchargent leurs fichiers de modèle à la première utilisation. Vous pouvez les préparer à l'avance.

POST /presets/prepare

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

Retourne 200 { "status": "already_installed" } ou 202 { "status": "started" } (le téléchargement s'exécute en arrière-plan).

GET /presets/prepare

Retourne les téléchargements en cours : { "downloads": [ ... ] }. Interrogez ceci, ou GET /capabilities (observez localReady), jusqu'à ce que la présélection soit prête.

Caractères

Character Studio est aussi scriptable. Les caractères sont locaux uniquement (le cloud est rejeté). Voir Caractères pour les concepts.

Point de terminaisonObjectif
GET /charactersLister les caractères.
GET /characters/:idObtenir un caractère.
GET /character-presetsPrésélections de caractères installées (base / edit / i2v).
GET /character-featuresOptions de fonction d'identité/apparence disponibles.
POST /charactersCréer un caractère (mode: "generate" à partir d'une description, ou "upload" à partir d'une poignée d'image de base téléchargée).
POST /characters/:id/generate-imageGénérer une image du caractère ({ prompt, aspect?, count?, presetId? }).
POST /characters/:id/generate-frameGénérer un seul cadre de début de vidéo.
POST /characters/:id/animateAnimer le caractère dans une vidéo.
POST /characters/:id/presetDéfinir la présélection par défaut du caractère.
POST /characters/:id/enhanceSurélever ou améliorer un actif de caractère. Nommez la source avec exactement l'un de target: "base", jobId (une génération précédente), ou handle (de POST /uploads). Optionnel : mediaType, presetId, scale, keepResolution, applyAsBase.

Tous les points de terminaison de génération retournent un jobId que vous interrogez via GET /jobs/:id, exactement comme POST /generate.

Recettes

Créez des recettes multi-étapes (flux) à partir de packs et présélections. Découvrez les blocs de construction, composez à partir d'une spécification haut niveau, puis publiez optionnellement.

Point de terminaisonObjectif
GET /recipe-blocksPoints d'entrée et chaque présélection utilisable comme étape, avec son contrat de port.
POST /recipes/validateEssai à vide d'une spec (composez+validez) ou d'une config, pas de sauvegarde. Retourne validation.
POST /recipesComposez à partir d'une spec et sauvegardez un brouillon. Retourne { recipeId, valid, errors, config }.
GET /recipesListe chaque recette sur cet appareil (installée depuis le Store ou créée ici) avec ses inputs (key, kind, label, required, options) et nombre d'étapes.
GET /recipes/:idObtenir une recette, sa config complète, ses inputs, et readiness (par étape : quelle présélection elle exécute et si elle est installée localement).
POST /recipes/:id/runExécuter une recette. Corps : { inputs: { key: value }, engine?: "local" | "cloud" | "auto" }. Les entrées Subject prennent un id de caractère ou de produit, les entrées image/vidéo/audio prennent des poignées de téléchargement, tout le reste prend des valeurs simples. Retourne { runId, status: "running", engine, steps, cloudCost? }. Les exécutions cloud sont tarifées à l'avance et décomptées du plafond de dépenses du jeton.
GET /recipes/:id/runsExécutions récentes d'une recette, la plus récente en premier.
GET /recipe-runs/:idStatut d'une exécution : status (running, completed, failed, cancelled), steps (chacun avec status, id de tâche et chemin de résultat) et resultPath une fois que l'étape média finale se termine.
POST /recipe-runs/:id/cancelArrêter une exécution. Aucune autre étape ne démarre ; une étape locale en vol est interrompue.
POST /recipes/:id/publishSoumettre à la Creator Marketplace (nécessite un compte connecté).

Produits et sujets

L'entrée subject d'une recette prend soit un caractère, soit un produit. Les produits sont l'autre type de sujet : une chose nommée avec une photo de base, utilisée par Product Studio et les recettes UGC.

Point de terminaisonObjectif
GET /subjectsChaque sujet qu'une recette peut prendre : caractères et produits (id, type, name, status).
GET /productsLister les produits.
GET /products/:idObtenir un produit.
POST /productsCréer un produit à partir d'une photo téléchargée : { name, image: <upload handle>, description?, category? }. La description et la catégorie sont tissées dans les invites de recette. Retourne { productId, product }.
DELETE /products/:idSupprimer un produit et sa photo.

Une spec est une description haut niveau ; l'application auto-câble les ports, la chaîne média étape par étape, et une entrée d'invite par étape, puis valide.

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

Composer et sauvegarder n'a besoin d'aucun compte créateur. POST /recipes/:id/publish nécessite un compte connecté et retourne not_connected (avec needsConnect: true) jusqu'à ce que l'utilisateur en connecte un dans l'application ; le même brouillon est alors publié inchangé. Chaque présélection que la recette utilise doit appartenir à un pack distributable propriétaire.

Video Studio

Les films sont des documents Video Studio : des clips (plans à rendre) sur une chronologie sur des pistes audio. Chaque itinéraire d'édition répond { change, timeline } : ce qui a changé, et la chronologie du film après (la même forme que GET /films/:id répond). Avec le film ouvert dans le studio, le changement s'affiche en direct et s'annule avec Ctrl+Z ; un film fermé est édité et sauvegardé.

Les clips sont nommés dans le chemin par id, par name, ou par number (leur ordre sur la chronologie, les plus anciens en premier). Les temps sont en secondes, ou en barres une fois que le film a un tempo : une position est 3, { "seconds": 3 } ou { "bar": 5 } (la barre 1 est le premier temps fort), une longueur est 5, { "seconds": 5 } ou { "bars": 2 }.

ItinéraireCe qu'il fait
GET /films?projectId=Films d'un projet (par défaut : le courant).
POST /filmsCréer un film : name, projectId optionnel, aspect (16:9, 9:16, 1:1), quality (480p, 720p, 1080p), renderOn (local, cloud), presets ({ t2v, i2v, r2v }). Répond la chronologie.
GET /films/:idLa chronologie.
PATCH /films/:idParamètres du film : aspect, quality, hires2x, renderOn, presets, subject, cast (noms ou ids), location (name, id ou null).
POST /films/:id/tracksAjouter une piste : upload (une poignée de POST /uploads), kind (singing, music, dialogue, effects), name, at.
PATCH /films/:id/tracks/:trackat, muted, volume (0 à 1).
POST /films/:id/tempoDétecter le tempo de la piste la plus longue non-asourdie, ou track. Répond { bpm, offset, track, timeline }.
POST /films/:id/clipsAjouter un clip : at, length, name, lane.
PATCH /films/:id/clips/:clipshots (chacun { prompt, seconds, line, speaker, framing }), cast, location ("none" abandonne celui du film, "film" le réhérite), link (fresh, continue, motion ; none et frame sont aussi acceptés, comme fresh et continue), hears ([{ track, on }]), preset.
POST /films/:id/clips/:clip/moveat, lane.
POST /films/:id/clips/:clip/trimlength, trimIn (où le clip commence à l'intérieur de sa prise ; 0 est le début de la prise).
DELETE /films/:id/clips/:clipSupprimer le clip.
POST /films/:id/planDisposer un brouillon (ci-dessous).
POST /films/:id/fadestarget (un clip ou une piste), fadeIn, fadeOut.
POST /films/:id/markersat, name.
POST /films/:id/export-rangefrom et to (tous deux requis), ou clear: true.
POST /films/:id/rendersRendre clips ("stale", par défaut, ou une liste). Répond 202 avec { started, held, credits } à la fois, ou 200 avec une note quand rien n'a besoin d'un rendu.
GET /films/:id/clips/:clip/takesLes prises du clip, la plus récente en premier.
POST /films/:id/clips/:clip/takegenerationId : faire de cette prise celle que le clip affiche.
POST /films/:id/exportAssembler le film. Répond 201 avec { path, resultUrl, blanks }.

Disposer un brouillon

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

Le plan est d'abord vérifié dans son ensemble. Un plan avec des problèmes répond 400 invalid_plan avec chaque problème dans details.problems (chacun préfixé avec son clip, comme clip 2: ...) et ne change rien. mode: "replace" remplace chaque clip et est refusé quand les clips ont des prises sauf si "discardTakes": true.

Rendus et plafond de dépenses

Un rendu cloud est tarifé avant que tout soit mis en file d'attente et décompte du plafond de dépenses du jeton : dépasser le plafond répond 402 exceeds_spend_cap, un prix inconnu 503 cost_unknown. Les clips qui continuent du clip précédent se rendent un à la fois, chacun après la prise d'où il commence ; l'appel répond à la fois, et GET /films/:id affiche la take de chaque clip : none, rendering, current, edited, longer, unknown (cela ne peut pas être dit encore) ou imported (une vidéo apportée, jamais rendue).

Emplacements

ItinéraireCe qu'il fait
GET /locationsLes emplacements de la Bibliothèque : id, name, description, hasPicture.
POST /locationsCréer un emplacement à partir de sa photo : name, description, et upload (une poignée) ou fromJob (une tâche d'image terminée).

Plafonds de dépenses

Quand un jeton a un plafond de dépenses, les générations cloud sont tarifées avant l'expédition et rejetées si elles dépassent l'allocation restante (402 exceeds_spend_cap). Si le coût ne peut pas être déterminé (statut cloud indisponible), un jeton plafonné échoue fermé avec 503 cost_unknown. Les générations locales sont toujours gratuites en termes de coût de crédit.

Un flux complet

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

Codes d'erreur

HTTPerrorCodeQuand
400invalid_jsonLe corps n'est pas un JSON valide.
400invalid_optionsUn champ obligatoire est manquant ou mal formé.
400invalid_presetPrésélection/pack/mediaType ne correspondent pas.
400needs_*Une entrée obligatoire (prompt, image, references) est manquante.
400invalid_handleUne entrée n'était pas une poignée de téléchargement valide.
400unsupported_backendLa présélection s'exécute sur une API externe.
400preset_not_installedBackend local choisi mais les modèles ne sont pas installés.
400cloud_not_connectedBackend cloud choisi mais aucun compte n'est connecté.
400invalid_planUn plan de film a des problèmes ; details.problems les énumère tous.
400no_tempoUn temps en barres avant que le film ait un tempo ; détectez d'abord le tempo.
400no_audioTempo demandé d'un film sans piste audio.
400no_pulseAucun battement régulier n'a pu être entendu dans la piste.
401unauthorizedJeton manquant ou invalide.
402exceeds_spend_capLe coût cloud dépasse le plafond de dépenses du jeton.
402exceeds_balanceLe solde cloud ne couvre pas les rendus.
403forbidden_hostEn-tête Host non-loopback.
403studio_not_installedVideo Studio n'est pas installé sur cet ordinateur.
404not_found / invalid_preset / job_not_foundItinéraire, présélection ou tâche inconnus.
404unknown_presetGET /prompt-guide/:presetId avec un id qui n'est pas une présélection.
404film_not_foundAucun film avec cet id.
404clip_not_foundAucun clip avec cet id, name ou number.
404track_not_foundAucune piste avec ce name ou id.
404cast_not_foundAucun caractère avec ce name ou id dans la Bibliothèque.
404location_not_foundAucun emplacement avec ce name ou id, ou il n'a pas de photo.
409clips_not_readyExport demandé alors que des clips ont encore besoin d'un rendu ; details.clips les nomme.
413asset_too_largeTéléchargement de plus de 100 MB.
503guides_unavailableLes guides d'invite n'ont pas pu être chargés et aucun n'est mis en cache.
503cost_unknownJeton plafonné ; le coût cloud n'a pas pu être déterminé.
503studio_busyLa fenêtre SimpliGen n'a pas pu être atteinte ou n'a pas répondu à temps. S'il y a eu un délai d'attente, le changement peut quand même avoir été fait : lisez le film avant de réessayer.
500internal_errorErreur serveur inattendue.