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{ "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
{ "name": "Campaign assets" }201을 반환하고 { "project": { ... } }입니다. name은 필수입니다(그렇지 않으면 400 invalid_options).
업로드
입력(소스 이미지, 참조 이미지, 소스 비디오)은 로컬 경로로 전달되지 않습니다. 먼저 바이트를 업로드하고 반환된 핸들을 POST /generate로 전달하세요.
POST /uploads
{ "filename": "ref.png", "dataBase64": "<base64 of the file bytes>" }{ "handle": "a1b2c3d4.png", "sizeBytes": 51234 }최대 업로드는 100 MB입니다(413 asset_too_large). 지원되지 않는 확장자는 400 unsupported_file_type를 반환합니다.
생성
POST /generate
생성을 큐에 넣고 즉시 jobId로 반환합니다. GET /jobs/:id를 폴링하세요(Jobs 참조) 결과를 위해.
{
"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 | 아니오 | 해상도 티어 레이블. |
{ "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(표시 이름)에서 일치합니다.
{
"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
{ "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 /recipes | spec에서 구성하고 드래프트 저장. { 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/publish | Creator 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은 고수준 설명입니다. 앱은 포트, 단계 간 미디어 체인 및 단계당 프롬프트 입력을 자동으로 연결한 다음, 검증합니다.
{
"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" } }
}구성 및 저장은 크리에이터 계정이 필요하지 않습니다. 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}'오류 코드
| HTTP | errorCode | 언제 |
|---|---|---|
| 400 | invalid_json | 본문이 유효한 JSON이 아닙니다. |
| 400 | invalid_options | 필수 필드가 누락되거나 형식이 잘못되었습니다. |
| 400 | invalid_preset | 프리셋/팩/mediaType 불일치. |
| 400 | needs_* | 필수 입력(프롬프트, 이미지, 참조)이 누락되었습니다. |
| 400 | invalid_handle | 입력이 유효한 업로드 핸들이 아니었습니다. |
| 400 | unsupported_backend | 프리셋이 외부 API에서 실행됩니다. |
| 400 | preset_not_installed | 로컬 백엔드를 선택했지만 모델이 설치되지 않았습니다. |
| 400 | cloud_not_connected | 클라우드 백엔드를 선택했지만 계정이 연결되지 않았습니다. |
| 401 | unauthorized | 누락되거나 유효하지 않은 토큰. |
| 402 | exceeds_spend_cap | 클라우드 비용이 토큰의 지출 한도를 초과합니다. |
| 403 | forbidden_host | 루프백이 아닌 Host 헤더. |
| 404 | not_found / invalid_preset / job_not_found | 알려지지 않은 경로, 프리셋 또는 작업. |
| 413 | asset_too_large | 100 MB 이상 업로드. |
| 503 | cost_unknown | 캡 된 토큰, 클라우드 비용을 결정할 수 없었습니다. |
| 500 | internal_error | 예상 외 서버 오류. |