Riferimento API di controllo
L'API HTTP locale che SimpliGen espone sul tuo computer, per creare integrazioni personalizzate ed eseguire generazioni in modalità headless.
SimpliGen esegue una piccola API di controllo HTTP sul tuo computer mentre l'app è aperta. È la stessa API con cui parla il server MCP, esposta direttamente affinché tu possa pilotare SimpliGen dai tuoi script, servizi o agent, anche con l'app ridotta a icona nella barra delle applicazioni.
MCP rispetto all'API di controllo
Se vuoi semplicemente che un agente IA (Claude, Codex, ecc.) utilizzi SimpliGen, configura invece il server MCP, che avvolge questa API. Usa l'API di controllo direttamente quando stai scrivendo un'integrazione personalizzata in qualsiasi linguaggio.
URL di base e scoperta
Il server si collega solo al loopback e va per impostazione predefinita a:
http://127.0.0.1:48199Se quella porta è occupata, SimpliGen ripiegherà su una porta assegnata dal sistema operativo. La porta corrente (e la versione dell'API) viene sempre scritta in un file di scoperta nella directory dei dati utente dell'app:
# Windows
%APPDATA%\simpligen\agent-api.json
# macOS
~/Library/Application Support/simpligen/agent-api.json
# Linux
~/.config/simpligen/agent-api.json{ "port": 48199, "version": 1 }Leggi questo file per trovare la porta live piuttosto che codificare hardcoded 48199.
Requisiti
L'API di controllo funziona solo quando l'app è aperta e la macchina è autorizzata per
l'accesso degli agenti (è parte della tua licenza). Le richieste vengono servite solo quando
l'intestazione Host è un alias loopback; qualsiasi altra cosa riceve 403 forbidden_host (una
protezione contro il DNS rebinding).
Autenticazione
Ogni endpoint eccetto GET /health richiede un token di accoppiamento nell'
intestazione Authorization:
Authorization: Bearer sg-agent-xxxxxxxx...Crea un token nell'app sotto Impostazioni → Connetti un agente (vedi Connetti un agente). Il token grezzo viene mostrato una sola volta: solo un hash viene archiviato. Ogni token può avere un facoltativo limite di spesa per le generazioni cloud. La revoca di un token nell'app ha effetto immediato.
Un token mancante o non valido restituisce 401 unauthorized.
Convenzioni
- Richieste: corpi JSON (
Content-Type: application/json), fino a 50 MB. - Risposte: sempre JSON.
- Errori: le risposte non 2xx hanno la forma
{ "errorCode": "...", "message": "..." }. - ID: i preset sono indirizzati da
presetId(più facoltativopackId); i job dajobId.
Una chiamata autenticata minima:
TOKEN="sg-agent-..."
curl -s http://127.0.0.1:48199/status -H "Authorization: Bearer $TOKEN"Salute
GET /health
Sonda di liveness. Nessuna autenticazione.
{ "ok": true, "name": "simpligen", "version": 1 }Capacità
GET /capabilities
Elenca ogni preset con cui puoi generare, un'entry per (preset, mediaType),
con i suoi input, opzioni, disponibilità locale e idoneità/costo 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
}
]
}| Campo | Significato |
|---|---|
localReady | Tutti i file del modello sono installati; il preset può essere eseguito localmente ora. |
cloudEligible | Il preset può essere eseguito su SimpliGen Cloud. |
cloudCost | Costo approssimativo in crediti per un'esecuzione cloud (null se non idoneo). |
apiProvider | Non null per i preset dell'API esterna (ad es. OpenAI, Google) che l'API di controllo non può inviare. |
inputs / options | Cosa accetta il preset e gli intervalli di opzioni/proporzioni d'aspetto che puoi passare a POST /generate. steps/cfg sono non null solo per i preset che espongono controlli avanzati. |
inputs.requiresPrompt | false per i preset le cui istruzioni sono incorporate (ritagli, scambi di testa o outfit, upscale): un prompt vuoto è valido e qualsiasi testo che invii viene aggiunto come note aggiuntive. |
Stato
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
Avvia il motore locale quando non è già in esecuzione. Non richiede corpo.
{ "engineRunning": true, "engineVersion": "v0.37.0", "engineStarting": false }Un avvio a freddo richiede più tempo di quello che la richiesta aspetta. Quando succede, la risposta è
202 con engineStarting: true e il motore continua ad avviarsi, quindi esegui il polling di
GET /status finché engineRunning non è true.
L'avvio di un motore che è già in esecuzione restituisce 200 con alreadyRunning: true
e non cambia nulla. Se nessun motore è installato, la risposta è 409 engine_not_installed: l'installazione di uno è un download multi gigabyte e rimane un
lavoro per l'app, non per l'API. Una macchina su cui il motore si rifiuta di funzionare risponde
409 engine_unsupported_hardware, che il retry non risolverà.
POST /engine/stop
Arresta il motore locale e libera la sua VRAM. La generazione cloud non è interessata. L'arresto di un motore che è già spento è un successo.
POST /engine/restart
Lo arresta e lo riavvia, per un motore bloccato o dopo che è stato installato o rimosso un nodo personalizzato. Lo stesso comportamento 202 di start quando l'avvio dura più della richiesta.
Progetti
I progetti sono i contenitori che contengono le generazioni.
GET /projects
{ "projects": [ { "id": "default", "name": "My Project", "slug": "my-project" } ] }POST /projects
{ "name": "Campaign assets" }Restituisce 201 con { "project": { ... } }. name è obbligatorio (altrimenti 400 invalid_options).
Upload
Gli input (immagini sorgente, immagini di riferimento, video sorgente) non vengono mai passati come
percorsi locali. Carica prima i byte e passa l'handle restituito a
POST /generate.
POST /uploads
{ "filename": "ref.png", "dataBase64": "<base64 of the file bytes>" }{ "handle": "a1b2c3d4.png", "sizeBytes": 51234 }L'upload massimo è 100 MB (413 asset_too_large). Le estensioni non supportate restituiscono
400 unsupported_file_type.
Genera
POST /generate
Accoda una generazione e restituisce immediatamente un jobId. Esegui il polling di
GET /jobs/:id (vedi Job) per il risultato.
{
"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" }
}| Campo | Obbligatorio | Note |
|---|---|---|
presetId | sì | Da GET /capabilities. |
mediaType | sì | "image" o "video". |
packId | no | Se fornito, deve corrispondere al pack del preset. |
prompt | condizionale | Obbligatorio a meno che il preset non riporti inputs.requiresPrompt: false. Questi preset hanno le loro istruzioni incorporate: invia "" per eseguirli così come sono, o aggiungi testo per passare note aggiuntive. |
backend | no | "auto" (impostazione predefinita), "local" o "cloud". Auto preferisce local se installato, altrimenti cloud se connesso. |
image | condizionale | Carica l'handle. Obbligatorio per i preset image-to-X (inputs.requiresImage). |
video | condizionale | Carica l'handle, per i preset con input video. |
referenceImages | condizionale | Array di handle o { handle, label }, per i preset con immagini di riferimento. |
audio | condizionale | Carica l'handle, per i preset guidati dall'audio (sincronizzazione labiale, audio-to-video). Obbligatorio quando il preset riporta acceptsAudio, altrimenti il job viene rifiutato con needs_audio. |
audioStartSeconds | no | Dove nel brano iniziare, in secondi. Accettato anche in options. |
referenceVideos | condizionale | Array di handle o { handle, soundtrackMode, durationSeconds }, per i preset di clip di riferimento. |
referenceAudios | condizionale | Array di handle o { handle, durationSeconds }, per i preset di suono di riferimento. |
loras | no | Array di { name, weight } da applicare, per i preset dove inputs.supportsLoras è true. name corrisponde al nome visualizzato di una LoRA (o al nome file) da GET /loras; weight imposta per impostazione predefinita la forza predefinita della LoRA. I nomi sconosciuti restituiscono 400 unknown_lora. Solo backend locale per ora. |
project | no | Project id o slug. Viene impostato per impostazione predefinita sul progetto attivo. |
options.aspectRatio | no | Deve essere uno dei rapporti supportati dal preset. |
options.steps / options.cfg | no | Entro gli intervalli pubblicizzati dal preset. |
options.negativePrompt | no | Prompt negativo (il prompt negativo delle opzioni avanzate dell'interfaccia utente). Accettato anche al livello superiore come negativePrompt. |
options.durationSeconds | no | Durata del video. |
options.resolution | no | Etichetta del livello di risoluzione. |
{ "jobId": "gen_abc123", "backend": "local", "status": "queued" }Per un job cloud, la risposta include anche "cloudCost": <credits>.
Backend
I preset dell'API esterna (dove apiProvider è non null, ad es. GPT Image 2, Veo)
non possono essere inviati qui, riceverai 400 unsupported_backend. Usa un preset locale
o SimpliGen Cloud. Cloud richiede un account connesso
(400 cloud_not_connected); local richiede i modelli installati
(400 preset_not_installed, preparali prima).
GET /loras
Elenca le LoRA installate dell'utente in modo che gli agenti possano scoprire cosa passare nell'
array loras di POST /generate. Abbina su name (il nome visualizzato).
{
"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 }
]
}Passa la LoRA dove si adatta al modello di base del preset (baseModel), e usa
le sue parole trigger nel tuo prompt in modo che si attivi.
Job
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 è uno di queued, processing, completed, failed. Al successo,
resultPath è il percorso del file locale decodificato; al fallimento, errorMessage spiega
perché. L'id sconosciuto restituisce 404 job_not_found.
GET /jobs
Restituisce i 25 job più recenti come { "jobs": [ ...job... ] }.
POST /jobs/:id/cancel
Annulla un job in coda o in esecuzione. Restituisce { "jobId", "status", "note?" }. Un job
cloud già in volo potrebbe comunque completarsi sul server (annotato in note).
Preparazione dei preset
I preset locali scaricano i loro file di modello al primo utilizzo. Puoi prepararli in anticipo.
POST /presets/prepare
{ "presetId": "z-image-turbo", "mediaType": "image" }Restituisce 200 { "status": "already_installed" } o 202 { "status": "started" }
(il download viene eseguito in background).
GET /presets/prepare
Restituisce i download in volo: { "downloads": [ ... ] }. Esegui il polling di questo, o di
GET /capabilities (guarda localReady), finché il preset non è pronto.
Caratteri
Character Studio è anch'esso scriptabile. I caratteri sono solo locali (cloud è rifiutato). Vedi Caratteri per i concetti.
| Endpoint | Scopo |
|---|---|
GET /characters | Elenca i caratteri. |
GET /characters/:id | Ottieni un carattere. |
GET /character-presets | Preset di caratteri installati (base / modifica / i2v). |
GET /character-features | Opzioni di caratteristiche di identità/aspetto disponibili. |
POST /characters | Crea un carattere (mode: "generate" da una descrizione, o "upload" da un handle di immagine di base caricato). |
POST /characters/:id/generate-image | Genera un'immagine del carattere ({ prompt, aspect?, count?, presetId? }). |
POST /characters/:id/generate-frame | Genera un singolo fotogramma di inizio video. |
POST /characters/:id/animate | Anima il carattere in un video. |
POST /characters/:id/preset | Imposta il preset predefinito del carattere. |
POST /characters/:id/enhance | Esegui l'upscale/migliora un asset di carattere. |
Tutti gli endpoint di generazione restituiscono un jobId che esegui il polling tramite GET /jobs/:id, esattamente
come POST /generate.
Ricette
Crea ricette multi-step (flussi) da pack e preset. Scopri i componenti base, componi da una specifica di alto livello, quindi opzionalmente pubblica.
| Endpoint | Scopo |
|---|---|
GET /recipe-blocks | Punti di ingresso e ogni preset utilizzabile come un passaggio, con il suo contratto di porta. |
POST /recipes/validate | Esecuzione a secco di uno spec (componi+convalida) o di un config, nessun salvataggio. Restituisce validation. |
POST /recipes | Componi da uno spec e salva una bozza. Restituisce { recipeId, valid, errors, config }. |
GET /recipes | Elenca ogni ricetta su questo dispositivo (installata dallo Store o creata qui) con i suoi inputs (chiave, tipo, etichetta, obbligatorio, opzioni) e conteggio dei passaggi. |
GET /recipes/:id | Ottieni una ricetta, la sua configurazione completa, i suoi inputs e readiness (per passaggio: quale preset esegue e se è installato localmente). |
POST /recipes/:id/run | Esegui una ricetta. Body: { inputs: { key: value }, engine?: "local" | "cloud" | "auto" }. Gli input dei soggetti richiedono un'id di carattere o prodotto, gli input di immagine/video/audio richiedono handle di caricamento, tutto il resto richiede valori semplici. Restituisce { runId, status: "running", engine, steps, cloudCost? }. Le esecuzioni cloud vengono valutate in anticipo e contegggiate rispetto al limite di spesa del token. |
GET /recipes/:id/runs | Esecuzioni recenti di una ricetta, le più recenti per prime. |
GET /recipe-runs/:id | Stato di un'esecuzione: status (in esecuzione, completato, non riuscito, annullato), steps (ognuno con stato, id del job e percorso del risultato) e resultPath una volta che il passaggio media finale si completa. |
POST /recipe-runs/:id/cancel | Arresta un'esecuzione. Nessun ulteriore passaggio inizia; un passaggio locale in volo viene interrotto. |
POST /recipes/:id/publish | Invia al Creator Marketplace (richiede un account connesso). |
Prodotti e soggetti
Un input subject di ricetta richiede un carattere o un prodotto. I prodotti sono l'altro tipo di soggetto: una cosa denominata con una foto di base, utilizzata da Product Studio e ricette UGC.
| Endpoint | Scopo |
|---|---|
GET /subjects | Ogni soggetto che una ricetta può richiedere: caratteri e prodotti (id, type, name, status). |
GET /products | Elenca i prodotti. |
GET /products/:id | Ottieni un prodotto. |
POST /products | Crea un prodotto da una foto caricata: { name, image: <upload handle>, description?, category? }. La descrizione e la categoria vengono tessute nei prompt delle ricette. Restituisce { productId, product }. |
DELETE /products/:id | Rimuovi un prodotto e la sua foto. |
Uno spec è una descrizione di alto livello; l'app collega automaticamente le porte, la
catena media da passaggio a passaggio e un input di prompt per passaggio, quindi convalida.
{
"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" } }
}La composizione e il salvataggio non richiedono un account di creatore. POST /recipes/:id/publish
richiede un account connesso e restituisce not_connected (con needsConnect: true)
finché l'utente non ne connette uno nell'app; la stessa bozza quindi si pubblica invariata.
Ogni preset utilizzato dalla ricetta deve appartenere a un pack di prima parte distribuibile.
Limiti di spesa
Quando un token ha un limite di spesa, le generazioni cloud vengono valutate prima dell'invio e
rifiutate se supererebbero l'indennità rimanente
(402 exceeds_spend_cap). Se il costo non può essere determinato (lo stato cloud non disponibile), un token coperto non riesce in modo chiuso con 503 cost_unknown. Le
generazioni locali sono sempre senza costo di credito.
Un flusso completo
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}'Codici di errore
| HTTP | errorCode | Quando |
|---|---|---|
| 400 | invalid_json | Il body non è un JSON valido. |
| 400 | invalid_options | Un campo obbligatorio è mancante o malformato. |
| 400 | invalid_preset | Mancata corrispondenza tra preset/pack/mediaType. |
| 400 | needs_* | Un input obbligatorio (prompt, immagine, riferimenti) è mancante. |
| 400 | invalid_handle | Un input non era un handle di caricamento valido. |
| 400 | unsupported_backend | Il preset viene eseguito su un'API esterna. |
| 400 | preset_not_installed | Backend locale scelto ma i modelli non sono installati. |
| 400 | cloud_not_connected | Backend cloud scelto ma nessun account è connesso. |
| 401 | unauthorized | Token mancante o non valido. |
| 402 | exceeds_spend_cap | Il costo cloud supera il limite di spesa del token. |
| 403 | forbidden_host | Intestazione Host non loopback. |
| 404 | not_found / invalid_preset / job_not_found | Route, preset o job sconosciuto. |
| 413 | asset_too_large | Upload oltre 100 MB. |
| 503 | cost_unknown | Token coperto; il costo cloud non potrebbe essere determinato. |
| 500 | internal_error | Errore server inaspettato. |