Référence de l'API de contrôle
L'API HTTP locale que SimpliGen expose sur votre machine, pour créer des intégrations personnalisées et exécuter des générations en mode headless.
SimpliGen exécute une petite API de contrôle HTTP sur votre machine pendant 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 lorsque l'application est réduite dans la barre système.
MCP vs l'API de contrôle
Si vous voulez simplement qu'un agent IA (Claude, Codex, etc.) utilise SimpliGen, configurez plutôt le serveur MCP, qui encapsule cette API. Utilisez l'API de contrôle directement lorsque vous écrivez une intégration personnalisée dans n'importe quel langage.
URL de base et découverte
Le serveur se lie à la loopback uniquement et utilise par défaut :
http://127.0.0.1:48199Si ce port est occupé, SimpliGen bascule vers un port attribué par le système d'exploitation. Le port actuel (et la version de l'API) sont toujours écrits dans un fichier de découverte dans le répertoire des 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{ "port": 48199, "version": 1 }Lisez ce fichier pour trouver le port actif plutôt que de coder en dur 48199.
Exigences
L'API de contrôle ne s'exécute que lorsque l'application est ouverte et que la machine est autorisée à
accès aux agents (cela fait partie de votre licence). Les demandes ne sont traitées que lorsque l'en-tête
Host est un alias loopback ; tout le reste reçoit 403 forbidden_host (une
protection contre le rebinding DNS).
Authentification
Chaque endpoint sauf GET /health nécessite un token d'appairage dans l'en-tête
Authorization :
Authorization: Bearer sg-agent-xxxxxxxx...Créez un token dans l'application sous Paramètres → Connecter un agent (voir Connecter un agent). Le token brut est affiché une seule fois ; seul un hash est stocké. Chaque token peut avoir un plafond de dépense optionnel pour les générations cloud. La révocation d'un token dans l'application prend effet immédiatement.
Un token manquant ou invalide retourne 401 unauthorized.
Conventions
- Demandes : 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 presets sont adressés par
presetId(+ optionnelpackId) ; les jobs parjobId.
Un appel authentifié minimal :
TOKEN="sg-agent-..."
curl -s http://127.0.0.1:48199/status -H "Authorization: Bearer $TOKEN"Health
GET /health
Sonde de vivacité. Pas d'authentification.
{ "ok": true, "name": "simpligen", "version": 1 }Capacités
GET /capabilities
Liste chaque preset avec lequel vous pouvez générer, une entrée par (preset, mediaType),
avec ses entrées, options, état de disponibilité locale et éligibilité/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
}
]
}| Champ | Signification |
|---|---|
localReady | Tous les fichiers de modèle sont installés ; le preset peut s'exécuter localement maintenant. |
cloudEligible | Le preset peut s'exécuter sur SimpliGen Cloud. |
cloudCost | Coût approximatif en crédits pour une exécution cloud (null s'il n'est pas éligible). |
apiProvider | Non-null pour les presets d'API externe (par ex. OpenAI, Google) que l'API de contrôle ne peut pas dispatcher. |
inputs / options | Ce que le preset accepte et les plages d'options/rapports d'aspect que vous pouvez passer à POST /generate. steps/cfg ne sont non-null que pour les presets qui exposent des contrôles avancés. |
inputs.requiresPrompt | false pour les presets dont les instructions sont intégrées (découpes, permutations de tête ou de tenue, surélévations) : un 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 n'est pas déjà en cours d'exécution. Ne prend pas de corps.
{ "engineRunning": true, "engineVersion": "v0.37.0", "engineStarting": false }Un démarrage à froid prend plus de temps que ce qu'une demande attend. Quand cela se produit, la réponse est
202 avec engineStarting: true et le moteur continue à démarrer, donc interrogez
GET /status jusqu'à ce que engineRunning soit vrai.
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 en est un téléchargement de plusieurs gigaoctets et reste une
tâche pour l'application, pas pour l'API. Une machine sur laquelle le moteur refuse de s'exécuter répond
409 engine_unsupported_hardware, ce que réessayer ne corrigera pas.
POST /engine/stop
Arrête le moteur local et libère sa VRAM. La génération cloud n'est pas affectée. L'arrêt d'un moteur qui est déjà arrêté est un succès.
POST /engine/restart
L'arrête et le redémarre, pour un moteur bloqué ou après l'installation ou la suppression d'un nœud personnalisé.
Le même comportement 202 que start quand le démarrage dépasse la durée de la demande.
Projets
Les projets sont les conteneurs qui conservent les générations.
GET /projects
{ "projects": [ { "id": "default", "name": "My Project", "slug": "my-project" } ] }POST /projects
{ "name": "Campaign assets" }Retourne 201 avec { "project": { ... } }. name est requis (400 invalid_options sinon).
Uploads
Les entrées (images source, images de référence, vidéos source) ne sont jamais passées en tant que
chemins locaux. Téléchargez d'abord les octets et passez le handle retourné à
POST /generate.
POST /uploads
{ "filename": "ref.png", "dataBase64": "<base64 of the file bytes>" }{ "handle": "a1b2c3d4.png", "sizeBytes": 51234 }Le téléchargement max est 100 MB (413 asset_too_large). Les extensions non supportées retournent
400 unsupported_file_type.
Générer
POST /generate
Met en file d'attente une génération et retourne immédiatement avec un jobId. Interrogez
GET /jobs/:id (voir Jobs) pour le résultat.
{
"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" }
}| Champ | Requis | Remarques |
|---|---|---|
presetId | oui | De GET /capabilities. |
mediaType | oui | "image" ou "video". |
packId | non | S'il est donné, doit correspondre au pack du preset. |
prompt | conditionnel | Requis sauf si le preset rapporte inputs.requiresPrompt: false. Ces presets ont leurs instructions intégrées : envoyez "" pour les exécuter tels quels, ou ajoutez du texte pour passer des notes supplémentaires. |
backend | non | "auto" (défaut), "local" ou "cloud". Auto préfère local s'il est installé, sinon cloud s'il est connecté. |
image | conditionnel | Handle de téléchargement. Requis pour les presets image-vers-X (inputs.requiresImage). |
video | conditionnel | Handle de téléchargement, pour les presets d'entrée vidéo. |
referenceImages | conditionnel | Tableau de handles ou { handle, label }, pour les presets d'image de référence. |
audio | conditionnel | Handle de téléchargement, pour les presets pilotés par audio (lip-sync, audio-vers-vidéo). Requis quand le preset rapporte acceptsAudio, sinon le job est rejeté avec needs_audio. |
audioStartSeconds | non | Où dans la piste commencer, en secondes. Aussi accepté sous options. |
referenceVideos | conditionnel | Tableau de handles ou { handle, soundtrackMode, durationSeconds }, pour les presets de clip de référence. |
referenceAudios | conditionnel | Tableau de handles ou { handle, durationSeconds }, pour les presets de son de référence. |
loras | non | Tableau de { name, weight } à appliquer, pour les presets où inputs.supportsLoras est vrai. name correspond au nom d'affichage (ou au nom de fichier) d'une LoRA de GET /loras ; weight utilise par défaut la force par défaut de la LoRA. Les noms inconnus retournent 400 unknown_lora. Backend local uniquement pour l'instant. |
project | non | id ou slug du projet. Par défaut au projet actif. |
options.aspectRatio | non | Doit être l'un des ratios supportés du preset. |
options.steps / options.cfg | non | Dans les plages annoncées du preset. |
options.negativePrompt | non | Prompt négatif (le négatif des Options avancées de l'IU). Aussi accepté au niveau supérieur en tant que negativePrompt. |
options.durationSeconds | non | Durée de la vidéo. |
options.resolution | non | Libellé du niveau de résolution. |
{ "jobId": "gen_abc123", "backend": "local", "status": "queued" }Pour un job cloud, la réponse inclut aussi "cloudCost": <credits>.
Backends
Les presets d'API externe (où apiProvider est non-null, par ex. GPT Image 2, Veo)
ne peuvent pas être dispatchés ici, vous obtiendrez 400 unsupported_backend. Utilisez un
preset local ou SimpliGen Cloud. Cloud nécessite un compte connecté
(400 cloud_not_connected) ; local nécessite que les modèles soient 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 puissent découvrir ce qu'il faut passer dans
le tableau loras de POST /generate. Correspondez sur name (le nom d'affichage).
{
"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 du preset (baseModel), et utilisez ses
propres mots déclencheurs dans votre prompt pour l'activer.
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 est l'un de queued, processing, completed, failed. En cas de succès,
resultPath est le chemin de fichier local décodé ; en cas d'échec, errorMessage explique
pourquoi. L'id inconnu retourne 404 job_not_found.
GET /jobs
Retourne les 25 jobs les plus récents en tant que { "jobs": [ ...job... ] }.
POST /jobs/:id/cancel
Annule un job en file d'attente/en cours d'exécution. Retourne { "jobId", "status", "note?" }. Un
job cloud déjà en vol peut toujours se terminer sur le serveur (noté dans note).
Préparation des presets
Les presets locaux téléchargent leurs fichiers de modèle à la première utilisation. Vous pouvez les préparer à l'avance.
POST /presets/prepare
{ "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 vol : { "downloads": [ ... ] }. Interrogez cela ou
GET /capabilities (regardez localReady), jusqu'à ce que le preset soit prêt.
Caractères
Character Studio est aussi scriptable. Les caractères sont locaux uniquement (cloud est rejeté). Voir Caractères pour les concepts.
| Endpoint | Objectif |
|---|---|
GET /characters | Lister les caractères. |
GET /characters/:id | Obtenir un caractère. |
GET /character-presets | Presets de caractères installés (base / edit / i2v). |
GET /character-features | Options de traits d'identité/apparence disponibles. |
POST /characters | Créer un caractère (mode: "generate" à partir d'une description, ou "upload" à partir d'un handle d'image de base téléchargée). |
POST /characters/:id/generate-image | Générer une image du caractère ({ prompt, aspect?, count?, presetId? }). |
POST /characters/:id/generate-frame | Générer une seule image de démarrage vidéo. |
POST /characters/:id/animate | Animer le caractère en vidéo. |
POST /characters/:id/preset | Définir le preset par défaut du caractère. |
POST /characters/:id/enhance | Surélever/améliorer un élément de caractère. |
Tous les endpoints de génération retournent un jobId que vous interrogez via GET /jobs/:id, exactement
comme POST /generate.
Recettes
Authorer des recettes multi-étapes (flux) hors des packs et presets. Découvrir les blocs de construction, composer à partir d'une spec haut niveau, puis éventuellement publier.
| Endpoint | Objectif |
|---|---|
GET /recipe-blocks | Points d'entrée + chaque preset utilisable en tant qu'étape, avec son contrat de port. |
POST /recipes/validate | Dry-run une spec (compose+validate) ou une config, pas de sauvegarde. Retourne validation. |
POST /recipes | Composer à partir d'une spec et sauvegarder un brouillon. Retourne { recipeId, valid, errors, config }. |
GET /recipes | Lister chaque recette sur cet appareil (installée à partir de la boutique ou créée ici) avec ses inputs (clé, genre, libellé, requis, options) et nombre d'étapes. |
GET /recipes/:id | Obtenir une recette, sa config complète, ses inputs, et readiness (par étape, quel preset elle exécute et s'il est installé localement). |
POST /recipes/:id/run | Exécuter une recette. Corps : { inputs: { key: value }, engine?: "local" | "cloud" | "auto" }. Les inputs de sujet prennent un id de caractère ou de produit, les inputs image/vidéo/audio prennent des handles 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 d'avance et comptent sur le plafond de dépense du token. |
GET /recipes/:id/runs | Exécutions récentes d'une recette, les plus récentes en premier. |
GET /recipe-runs/:id | Statut d'une exécution : status (running, completed, failed, cancelled), steps (chacun avec statut, id de job et chemin de résultat) et resultPath une fois que la dernière étape médias se termine. |
POST /recipe-runs/:id/cancel | Arrêter une exécution. Aucune étape supplémentaire ne commence ; une étape en vol locale est interrompue. |
POST /recipes/:id/publish | Soumettre à la Place du Créateur (nécessite un compte connecté). |
Produits et sujets
L'input 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.
| Endpoint | Objectif |
|---|---|
GET /subjects | Chaque sujet qu'une recette peut prendre : caractères et produits (id, type, name, status). |
GET /products | Lister les produits. |
GET /products/:id | Obtenir un produit. |
POST /products | Cré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 prompts de recette. Retourne { productId, product }. |
DELETE /products/:id | Retirer un produit et sa photo. |
Une spec est une description haut niveau ; l'app auto-câble les ports, la chaîne
média étape-à-étape, et un input prompt par étape, puis valide.
{
"spec": {
"name": "Product to spinning video",
"category": "product",
"steps": [
{ "preset": "krea2-pack:krea2-turbo" },
{ "preset": "wan-2.2-video-pack:wan-2.2-i2v" }
]
}
}{
"recipeId": "b1f2…",
"valid": true,
"errors": [],
"config": { "blocks": [ "…" ], "inputs": [ "…" ], "output": { "from": "n2.video" } }
}Composer et sauvegarder ne nécessite pas de 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'app ; le même brouillon publie alors inchangé.
Chaque preset utilisé par la recette doit appartenir à un pack propriétaire de première partie distribuable.
Plafonds de dépense
Quand un token a un plafond de dépense, les générations cloud sont tarifées avant dispatch et
rejetées si elles dépasseraient l'allocation restante
(402 exceeds_spend_cap). Si le coût ne peut pas être déterminé (statut cloud
indisponible), un token 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
| HTTP | errorCode | Quand |
|---|---|---|
| 400 | invalid_json | Le corps n'est pas du JSON valide. |
| 400 | invalid_options | Un champ requis est manquant ou mal formé. |
| 400 | invalid_preset | Preset/pack/mediaType ne correspondent pas. |
| 400 | needs_* | Un input requis (prompt, image, références) est manquant. |
| 400 | invalid_handle | Un input n'était pas un handle de téléchargement valide. |
| 400 | unsupported_backend | Le preset s'exécute sur une API externe. |
| 400 | preset_not_installed | Backend local choisi mais les modèles ne sont pas installés. |
| 400 | cloud_not_connected | Backend cloud choisi mais aucun compte n'est connecté. |
| 401 | unauthorized | Token manquant ou invalide. |
| 402 | exceeds_spend_cap | Le coût cloud dépasse le plafond de dépense du token. |
| 403 | forbidden_host | En-tête Host non-loopback. |
| 404 | not_found / invalid_preset / job_not_found | Route, preset ou job inconnu. |
| 413 | asset_too_large | Upload dépassant 100 MB. |
| 503 | cost_unknown | Token plafonné ; le coût cloud n'a pas pu être déterminé. |
| 500 | internal_error | Erreur serveur inattendue. |