SimpliGen Docs
AI Agents

Control API 레퍼런스

SimpliGen이 당신의 머신에서 실행하는 로컬 HTTP API로, 커스텀 통합을 구축하고 헤드리스 생성을 실행하기 위한 것입니다.

SimpliGen은 앱이 열려있는 동안 당신의 머신에서 작은 HTTP Control API를 실행합니다. 이것은 MCP 서버가 사용하는 동일한 API이며, 직접 노출되어 있어서 당신은 당신 자신의 스크립트, 서비스 또는 에이전트에서 SimpliGen을 제어할 수 있으며, 앱을 트레이로 최소화한 상태에서도 가능합니다.

MCP vs Control API

AI 에이전트(Claude, Codex 등)가 SimpliGen을 사용하게 하고 싶다면, 대신 MCP 서버를 설정하세요. 이것은 이 API를 래핑합니다. 다양한 언어로 커스텀 통합을 작성할 때 Control API를 직접 사용하세요.

기본 URL과 발견

서버는 로컬호스트 전용으로 바인딩되며 기본값은:

http://127.0.0.1:48199

그 포트가 사용 중이면 SimpliGen은 OS가 할당한 포트로 폴백합니다. 현재 포트(및 API 버전)는 항상 앱의 사용자 데이터 디렉토리의 발견 파일에 기록됩니다:

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

48199를 하드코딩하는 대신 이 파일을 읽어 현재 포트를 찾으세요.

요구사항

Control API는 앱이 열려있고 머신이 에이전트 액세스를 받을 자격이 있을 때만 실행됩니다(이것은 당신의 라이선스의 일부입니다). 요청은 Host 헤더가 루프백 별칭일 때만 제공됩니다. 그 외의 경우 403 forbidden_host를 받습니다(DNS 리바인딩 가드).

인증

GET /health를 제외한 모든 엔드포인트는 Authorization 헤더에 페어링 토큰이 필요합니다:

Authorization: Bearer sg-agent-xxxxxxxx...

앱의 설정 → 에이전트 연결에서 토큰을 만드세요(에이전트 연결 참조). 원본 토큰은 한 번만 표시되며, 해시만 저장됩니다. 각 토큰은 클라우드 생성에 대한 선택적 지출 한도를 가질 수 있습니다. 앱에서 토큰을 취소하면 즉시 적용됩니다.

누락되거나 유효하지 않은 토큰은 401 unauthorized를 반환합니다.

규칙

  • 요청: JSON 본문(Content-Type: application/json), 최대 50 MB.
  • 응답: 항상 JSON.
  • 오류: 2xx가 아닌 응답은 { "errorCode": "...", "message": "..." } 형태입니다.
  • ID: 프리셋은 presetId(+ 선택적 packId)로 주소가 지정되고, 작업은 jobId로 주소가 지정됩니다.

최소한의 인증된 호출:

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

헬스

GET /health

라이브니스 프로브. 인증 불필요.

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

기능

GET /capabilities

당신이 생성할 수 있는 모든 프리셋을 나열합니다, (preset, mediaType)당 하나의 항목씩, 입력, 옵션, 로컬 준비 상태 및 클라우드 적격 여부/비용을 포함합니다.

{
  "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
    }
  ]
}
필드의미
localReady모든 모델 파일이 설치되었으며, 프리셋을 지금 로컬에서 실행할 수 있습니다.
cloudEligible프리셋을 SimpliGen Cloud에서 실행할 수 있습니다.
cloudCost클라우드 실행에 대한 대략적인 크레딧 비용(적격이 아닐 경우 null).
apiProvider외부 API 프리셋(예: OpenAI, Google)의 경우 null이 아니며, Control API는 이를 디스패치할 수 없습니다.
inputs / options프리셋이 수용하는 것과 POST /generate로 전달할 수 있는 옵션 범위/종횡비. steps/cfg는 고급 컨트롤을 노출하는 프리셋에만 null이 아닙니다.
inputs.requiresPrompt지침이 내장된 프리셋(자르기, 헤드 또는 복장 스왑, 업스케일)의 경우 false입니다. 빈 prompt는 유효하며, 당신이 보내는 모든 텍스트는 추가 메모로 추가됩니다.

상태

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

로컬 엔진이 아직 실행 중이 아닐 때 시작합니다. 본문을 받지 않습니다.

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

콜드 부팅은 요청이 대기하는 시간보다 오래 걸립니다. 그런 경우 응답은 202이고 engineStarting: true이며, 엔진은 계속 부팅되므로, engineRunning이 true가 될 때까지 GET /status를 폴링하세요.

이미 실행 중인 엔진을 시작하면 200이 반환되고 alreadyRunning: true이며 아무것도 변경되지 않습니다. 엔진이 설치되지 않았으면 응답은 409 engine_not_installed입니다. 엔진을 설치하는 것은 여러 기가바이트의 다운로드이며 앱의 작업으로 남습니다, API의 작업이 아닙니다. 엔진이 실행을 거부하는 머신은 409 engine_unsupported_hardware를 응답하며, 재시도해도 고쳐지지 않습니다.

POST /engine/stop

로컬 엔진을 중지하고 VRAM을 해제합니다. 클라우드 생성은 영향을 받지 않습니다. 이미 꺼진 엔진을 중지하는 것은 성공입니다.

POST /engine/restart

멈춘 엔진이나 커스텀 노드가 설치되거나 제거된 후를 위해 다시 중지하고 시작합니다. 부팅이 요청을 초과할 때와 동일한 202 동작입니다.

프로젝트

프로젝트는 생성을 보유하는 컨테이너입니다.

GET /projects

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

POST /projects

Request
{ "name": "Campaign assets" }

201을 반환하고 { "project": { ... } }입니다. name은 필수입니다(그렇지 않으면 400 invalid_options).

업로드

입력(소스 이미지, 참조 이미지, 소스 비디오)은 로컬 경로로 전달되지 않습니다. 먼저 바이트를 업로드하고 반환된 핸들을 POST /generate로 전달하세요.

POST /uploads

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

최대 업로드는 100 MB입니다(413 asset_too_large). 지원되지 않는 확장자는 400 unsupported_file_type를 반환합니다.

생성

POST /generate

생성을 큐에 넣고 즉시 jobId로 반환합니다. GET /jobs/:id를 폴링하세요(Jobs 참조) 결과를 위해.

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" }
}
필드필수참고
presetId예GET /capabilities에서.
mediaType예"image" 또는 "video".
packId아니오주어지면, 프리셋의 팩과 일치해야 합니다.
prompt조건부프리셋이 inputs.requiresPrompt: false를 보고하지 않는 한 필수입니다. 이러한 프리셋들은 지침이 내장되어 있습니다: ""를 보내 그대로 실행하거나, 추가 메모를 전달하려면 텍스트를 추가하세요.
backend아니오"auto"(기본값), "local" 또는 "cloud". 자동은 로컬을 선호하며 설치되지 않았으면 클라우드를 선호합니다.
image조건부업로드 핸들. 이미지 대 X 프리셋(inputs.requiresImage)에 필수입니다.
video조건부비디오 입력 프리셋을 위한 업로드 핸들.
referenceImages조건부참조 이미지 프리셋을 위한 핸들이나 { handle, label } 배열.
audio조건부오디오 기반 프리셋(입술 싱크, 오디오 대 비디오)을 위한 업로드 핸들. 프리셋이 acceptsAudio를 보고할 때 필수입니다. 그렇지 않으면 작업은 needs_audio로 거부됩니다.
audioStartSeconds아니오트랙에서 시작할 위치, 초 단위. 또한 options에서 수용됩니다.
referenceVideos조건부참조 클립 프리셋을 위한 핸들이나 { handle, soundtrackMode, durationSeconds } 배열.
referenceAudios조건부참조 음향 프리셋을 위한 핸들이나 { handle, durationSeconds } 배열.
loras아니오inputs.supportsLoras가 true인 프리셋을 위해 { name, weight }의 배열을 적용합니다. name은 GET /loras의 LoRA의 표시 이름(또는 파일명)과 일치합니다. weight는 LoRA의 기본 강도로 기본값입니다. 알려지지 않은 이름은 400 unknown_lora를 반환합니다. 지금은 로컬 백엔드 전용입니다.
project아니오프로젝트 id 또는 slug. 활성 프로젝트로 기본값입니다.
options.aspectRatio아니오프리셋의 지원하는 비율 중 하나여야 합니다.
options.steps / options.cfg아니오프리셋의 공표된 범위 내.
options.negativePrompt아니오부정적 프롬프트(UI의 고급 옵션 부정). 또한 최상위 레벨에서 negativePrompt로 수용됩니다.
options.durationSeconds아니오비디오 지속 시간.
options.resolution아니오해상도 티어 레이블.
Response (201)
{ "jobId": "gen_abc123", "backend": "local", "status": "queued" }

클라우드 작업의 경우 응답은 또한 "cloudCost": <credits>를 포함합니다.

백엔드

외부 API 프리셋(apiProvider가 null이 아닌, 예: GPT Image 2, Veo)은 여기서 디스패치될 수 없으며, 400 unsupported_backend를 얻을 것입니다. 로컬 또는 SimpliGen Cloud 프리셋을 사용하세요. 클라우드는 연결된 계정(400 cloud_not_connected)이 필요합니다. 로컬은 모델이 설치되어 있어야 합니다(400 preset_not_installed, 먼저 준비하세요).

GET /loras

사용자의 설치된 LoRA를 나열하므로 에이전트는 POST /generate의 loras 배열에서 전달할 것을 발견할 수 있습니다. name(표시 이름)에서 일치합니다.

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

프리셋의 기본 모델(baseModel)이 맞는 곳에 LoRA를 전달하고, 활성화되도록 프롬프트에서 고유의 트리거 단어를 사용하세요.

작업

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는 queued, processing, completed, failed 중 하나입니다. 성공 시, resultPath는 디코딩된 로컬 파일 경로입니다. 실패 시, errorMessage가 이유를 설명합니다. 알려지지 않은 id는 404 job_not_found를 반환합니다.

GET /jobs

가장 최근 25개 작업을 { "jobs": [ ...job... ] }로 반환합니다.

POST /jobs/:id/cancel

큐에 넣어진/실행 중인 작업을 취소합니다. { "jobId", "status", "note?" }를 반환합니다. 이미 중인 클라우드 작업은 여전히 서버에서 완료될 수 있습니다(note에 명시됨).

프리셋 준비

로컬 프리셋은 처음 사용할 때 모델 파일을 다운로드합니다. 미리 준비할 수 있습니다.

POST /presets/prepare

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

200 { "status": "already_installed" } 또는 202 { "status": "started" }를 반환합니다(다운로드는 백그라운드에서 실행됨).

GET /presets/prepare

중인 다운로드를 반환합니다: { "downloads": [ ... ] }. 이를 폴링하거나, GET /capabilities를 폴링하세요(localReady 감시), 프리셋이 준비될 때까지.

캐릭터

Character Studio도 스크립트 가능합니다. 캐릭터는 로컬 전용입니다(클라우드는 거부됨). 캐릭터의 개념을 참조하세요.

엔드포인트목적
GET /characters캐릭터 나열.
GET /characters/:id한 캐릭터 얻기.
GET /character-presets설치된 캐릭터 프리셋(기본 / 편집 / i2v).
GET /character-features사용 가능한 신원/외형 기능 옵션.
POST /characters캐릭터 만들기(mode: "generate" 설명으로부터, 또는 "upload" 업로드된 기본 이미지 핸들로부터).
POST /characters/:id/generate-image캐릭터의 이미지 생성({ prompt, aspect?, count?, presetId? }).
POST /characters/:id/generate-frame단일 비디오 시작 프레임 생성.
POST /characters/:id/animate캐릭터를 비디오로 애니메이트.
POST /characters/:id/preset캐릭터의 기본 프리셋 설정.
POST /characters/:id/enhance캐릭터 자산 업스케일/향상.

모든 생성 엔드포인트는 GET /jobs/:id를 통해 폴링하는 jobId를 반환하며, POST /generate과 정확히 같습니다.

레시피

팩 및 프리셋으로부터 다단계 레시피(흐름)를 작성합니다. 구성 요소를 발견하고, 고수준 사양에서 구성한 다음, 선택적으로 발행합니다.

엔드포인트목적
GET /recipe-blocks진입점 + 단계로 사용 가능한 모든 프리셋, 포트 계약 포함.
POST /recipes/validate드라이 실행 spec(구성+검증) 또는 config, 저장 없음. validation을 반환합니다.
POST /recipesspec에서 구성하고 드래프트 저장. { recipeId, valid, errors, config }를 반환합니다.
GET /recipes이 기기의 모든 레시피(스토어에서 설치되거나 여기서 작성됨)를 inputs(키, 종류, 레이블, 필수, 옵션)와 단계 개수로 나열합니다.
GET /recipes/:id한 레시피, 전체 구성, inputs 및 readiness(단계당: 실행하는 프리셋과 로컬에 설치되는지 여부)를 얻기.
POST /recipes/:id/run레시피 실행. 본문: { inputs: { key: value }, engine?: "local" | "cloud" | "auto" }. 주제 입력은 캐릭터 또는 제품 id를 가지고, 이미지/비디오/오디오 입력은 업로드 핸들을 가지고, 다른 모든 것은 평문 값을 가집니다. { runId, status: "running", engine, steps, cloudCost? }를 반환합니다. 클라우드 실행은 미리 가격 책정되고 토큰의 지출 한도에 반하여 계산됩니다.
GET /recipes/:id/runs레시피의 최근 실행, 최신 우선.
GET /recipe-runs/:id실행 상태: status(실행 중, 완료, 실패, 취소), steps(각각 상태, 작업 id 및 결과 경로 포함) 및 마지막 미디어 단계가 완료되면 resultPath.
POST /recipe-runs/:id/cancel실행 중지. 추가 단계는 시작되지 않으며, 로컬 중인 단계는 중단됩니다.
POST /recipes/:id/publishCreator Marketplace에 제출(연결된 계정 필요).

제품 및 주제

레시피의 subject 입력은 캐릭터 또는 제품을 가집니다. 제품은 다른 주제 유형입니다: 기본 사진이 있는 명명된 것, Product Studio 및 UGC 레시피에서 사용됩니다.

엔드포인트목적
GET /subjects레시피가 가져갈 수 있는 모든 주제: 캐릭터 및 제품(id, type, name, status).
GET /products제품 나열.
GET /products/:id한 제품 얻기.
POST /products업로드된 사진으로부터 제품 만들기: { name, image: <upload handle>, description?, category? }. 설명과 카테고리는 레시피 프롬프트에 짜여집니다. { productId, product }를 반환합니다.
DELETE /products/:id제품 및 그 사진 제거.

spec은 고수준 설명입니다. 앱은 포트, 단계 간 미디어 체인 및 단계당 프롬프트 입력을 자동으로 연결한 다음, 검증합니다.

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

구성 및 저장은 크리에이터 계정이 필요하지 않습니다. POST /recipes/:id/publish는 연결된 계정이 필요하며, 사용자가 앱에서 하나를 연결할 때까지 not_connected(needsConnect: true 포함)를 반환합니다. 그 동일한 드래프트가 변경되지 않고 발행됩니다. 레시피가 사용하는 모든 프리셋은 배포 가능한 일차 팩에 속해야 합니다.

지출 한도

토큰이 지출 한도를 가질 때, 클라우드 생성은 디스패치 전에 가격 책정되고, 남은 여유를 초과하면 거부됩니다(402 exceeds_spend_cap). 비용을 결정할 수 없으면(클라우드 상태 불가능), 캡 된 토큰은 닫혀 실패합니다 503 cost_unknown. 로컬 생성은 항상 크레딧 비용이 없습니다.

완전한 흐름

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

오류 코드

HTTPerrorCode언제
400invalid_json본문이 유효한 JSON이 아닙니다.
400invalid_options필수 필드가 누락되거나 형식이 잘못되었습니다.
400invalid_preset프리셋/팩/mediaType 불일치.
400needs_*필수 입력(프롬프트, 이미지, 참조)이 누락되었습니다.
400invalid_handle입력이 유효한 업로드 핸들이 아니었습니다.
400unsupported_backend프리셋이 외부 API에서 실행됩니다.
400preset_not_installed로컬 백엔드를 선택했지만 모델이 설치되지 않았습니다.
400cloud_not_connected클라우드 백엔드를 선택했지만 계정이 연결되지 않았습니다.
401unauthorized누락되거나 유효하지 않은 토큰.
402exceeds_spend_cap클라우드 비용이 토큰의 지출 한도를 초과합니다.
403forbidden_host루프백이 아닌 Host 헤더.
404not_found / invalid_preset / job_not_found알려지지 않은 경로, 프리셋 또는 작업.
413asset_too_large100 MB 이상 업로드.
503cost_unknown캡 된 토큰, 클라우드 비용을 결정할 수 없었습니다.
500internal_error예상 외 서버 오류.