Spicy Schema 계약
공통 요청 형식, 표준 필드, 폼 스키마, 비동기 수명 주기, 오류, 결과 저장과 호환 규칙입니다.
Spicy Schema는 모든 새 미디어 모델의 공개 계약입니다. 모델이 추가되면 model, inputSchema와 고객 가격이 달라지지만 인증, 작업, 결과, 오류와 다운로드는 같습니다.
이 페이지는 참조 문서입니다. 대부분의 통합에는 모델 카탈로그와 스키마면 충분합니다. inputSchema로 폼, 검증기나 코드 생성기를 만들며 어떤 규칙을 신뢰할 수 있는지 정확히 알아야 할 때 읽으세요.
호출 가능 여부는 최신 카탈로그에서만 확인됩니다
이 페이지는 계약 형식을 정의하며 모델이 실제 제공 중이라고 주장하지 않습니다. 유료 작업 전에 인증된 GET /api/v1/models 응답에서 enabled: true와 available: true를 모두 확인하세요. 예정·비활성 항목은 호출할 수 없습니다.
공개 범위
공개 모델 ID는 <publisher>/<model>/<task> 형식으로 안정적인 기능 하나를 식별합니다. publisher는 모델을 만든 저자나 연구기관입니다. 이미지 편집은 항상 edit 접미사를 사용하며 이전에 공개된 식별자도 계속 허용됩니다. 실제 ID는 최신 카탈로그에서 복사하세요. 이 페이지의 MODEL_ID_FROM_CATALOG는 자리표시자입니다.
공개 응답, webhook, 오류와 다운로드는 SpicyAPI 자체 식별자·오류 코드·URL만 사용합니다. 내부 처리 정보, 원본 응답·오류와 내부 사업 정보를 포함하지 않습니다. 결과는 반환 전에 SpicyAPI 자체 저장소에 복사됩니다.
공통 생성 요청 형식
{
"model": "MODEL_ID_FROM_CATALOG",
"input": {
"prompt": "slow camera push-in",
"image_url": "spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3",
"duration_seconds": 8,
"resolution": "1080p",
"generate_audio": true
},
"callBackUrl": "https://your-app.example.com/hooks/spicy"
}| 필드 | 규칙 |
|---|---|
model | 인증된 최신 카탈로그의 정확한 현재 호출 가능 값 |
input | 같은 항목의 현재 inputSchema 충족. 알 수 없는 필드는 거절 |
callBackUrl | 완료 작업을 받는 선택적 공개 HTTPS 주소. 대소문자까지 이 표기 사용. Webhook 참조 |
위 input은 설명용입니다. 모델이 받는 필드는 해당 모델의 inputSchema만 정의합니다.
표준 필드
모든 새 엔드포인트는 같은 개념에 같은 snake_case 이름을 사용합니다. 표는 일반적인 필드이며 전체 목록은 아닙니다. 전체 목록은 항상 모델의 inputSchema입니다.
| 개념 | 필드 | 유형 |
|---|---|---|
| 원하는 내용의 프롬프트 | prompt | 문자열 |
| 제외할 내용의 프롬프트 | negative_prompt | 문자열 |
| 첫 이미지 / 마지막 이미지 | image_url / last_image_url | 이미지 참조(아래 참조) |
| 여러 입력 이미지 | image_urls | 이미지 참조 배열 |
| 편집 마스크 | mask_url | 이미지 참조 |
| 주 영상 / 오디오 | video_url / audio_url | 공개 HTTPS URL 또는 확정된 spicy:// URI |
| 참조 미디어 | reference_image_urls / reference_video_urls / reference_audio_urls | 참조 배열 |
| 출력 길이 | duration_seconds | 숫자 또는 정수 |
| 해상도 / 비율 | resolution / aspect_ratio | 문서에 명시된 열거값 |
| 정확한 출력 크기 | 프리셋 size 또는 width / height | 문서에 명시된 열거값 / 정수 |
| 프레임 속도 | fps | 정수 |
| 기본 오디오 생성 | generate_audio | 불리언 |
| 난수 시드 | seed | 정수 |
| 추가 가중치 | loras 또는 단계를 별도로 제공할 때 high_noise_loras / low_noise_loras | 객체 배열 |
| 출력 개수 | num_outputs | 양의 정수 |
| 인코딩 | output_format | 문서에 명시된 열거값 |
| 채팅 대화 | messages | 배열 |
| 출력 길이 / 샘플링 | max_tokens / temperature | 정수 / 숫자 |
이미지 참조는 공개 HTTPS URL, 업로드에서 얻은 확정 spicy:// URI 또는 작은 data:image/…;base64,… URI입니다. 영상과 오디오는 인라인으로 보낼 수 없습니다. 미디어를 참고하세요.
추가 가중치 항목은 적용할 가중치 세트 하나와 적용 강도를 지정합니다. 필드명은 고정되지만 항목 구조는 아닙니다. 파일 URL인지 내장 라이브러리 키인지는 각 엔드포인트의 items 하위 스키마가 정의하므로 특정 형식을 가정하지 말고 확인하세요. 허용 항목 수와 필수 하위 필드도 마찬가지입니다.
모델 전용 필드는 기존 표준 필드로 표현할 수 없는 실제 기능이 있을 때만 존재하며 기능에 맞게 이름을 짓습니다. 오래된 엔드포인트는 최신 inputSchema에 이전 필드명을 유지할 수 있지만 새 엔드포인트는 이를 복사하지 않습니다.
inputSchema와 UI 주석
모든 모델의 inputSchema는 JSON Schema 2020-12입니다. 같은 스키마가 서버 검증, Playground 폼, 예시와 견적을 제어합니다. 공식 TypeScript SDK는 공통 요청·응답을 정적으로 타입 지정합니다. 모델별 input은 Record<string, unknown>이므로 생성된 모델별 필드가 있다고 가정하지 말고 최신 스키마로 검증해야 합니다.
이 사이트는 모델별 정적 매개변수 표를 두지 않습니다. 기준은 GET /api/v1/models?includeSchema=1의 inputSchema 하나이며 Playground도 이를 렌더링합니다. 정적 사본은 모델 변경에 따라 낡고 이를 확실히 잡아낼 수 없습니다. 자체 표 구성은 모델 카탈로그와 스키마를 참고하세요.
반환되는 모든 스키마는 다음 규칙을 따릅니다.
- 루트가
object이며 알 수 없는 필드를 거절합니다(additionalProperties: false). required, 유형, 열거값, 범위, 길이, 배열 한도, URI 형식, 기본값과 검증된 조건을 명시합니다.- 모든 속성에 비어 있지 않은 영어
description을 제공합니다. - 검증하지 않은 필드와 기본값은 추측하지 않고 생략합니다.
- 조건은 UI 표시 여부만으로 표현하지 않고 루트
anyOf/allOf로 표현합니다(아래 참조). - 내부 처리만 바꾸는 스위치나 콘텐츠 필터 스위치는 없습니다.
표시 주석: x-ui
표시 메타데이터는 별도 검증 스키마가 아닙니다. 모두 속성 자체의 x-ui 객체에 있으며 키는 snake_case인 다음 고정 집합입니다.
| 키 | 의미 |
|---|---|
widget | 표시할 컨트롤. 값은 아래 참조 |
order | 필드 순서를 정하는 기준. 큰 값 우선, 엔드포인트 내 고유 |
label / placeholder | 기본 라벨 재정의 / 입력 자리표시자 |
rows | 텍스트 영역 행 수 |
step / unit | 숫자 증분과 단위 접미사(s, px) |
accept / max_size_mb | 업로드 MIME 필터와 파일별 크기 한도 |
advanced | 접힌 고급 영역에 배치 |
primary | 주요 입력. 위에 고정하며 접지 않음 |
affects_price | 변경 시 새 견적 필요 |
visible_when | 조건부 표시 표현식 |
enum_labels | 열거값의 표시 라벨 |
x-ui.widget은 13가지 중 하나입니다: textarea, text, upload, multi-upload, select, radio, slider, number, switch, json, object-list, chat-messages, hidden. 위젯은 항상 데이터 구조와 일치하므로 직접 분기할 수 있습니다. select와 radio는 항상 enum이 있습니다. slider는 minimum과 maximum을 모두 가집니다(exclusiveMinimum / exclusiveMaximum만 있는 경우는 없음). switch는 항상 boolean입니다. multi-upload는 items.type: string 배열입니다. object-list는 items.type: object와 items.properties가 있는 배열이며 하위 필드마다 자체 type과 description이 있습니다. chat-messages는 배열입니다. hidden은 컨트롤은 없지만 필드는 계속 제출한다는 뜻입니다.
배열의 minItems / maxItems와 items 하위 스키마는 루트 required에 나오지 않는 제약도 담으며 서버가 동일하게 적용합니다. object-list의 items는 자체 required, additionalProperties: false, 하위 필드별 유형·범위·default를 갖는 완전한 객체 스키마입니다. 기본값은 내부 항목에도 적용됩니다. 생략한 하위 필드는 검증 전에 default로 채우므로 필수이면서 기본값이 있으면 실질적으로 선택 사항입니다. 기본값 없는 필수 필드, 알 수 없는 하위 필드와 범위를 벗어난 값은 거절합니다.
배열 내부 값으로 발생한 400은 요청 전체가 아니라 정확한 필드, 0부터 시작하는 항목 번호와 하위 필드를 가리킵니다. 수정할 사람에게 이 경로를 전달하세요. 항목이 여러 개일 때 오류 위치를 알면 하나만 수정하면 되며 일일이 원인을 좁힐 필요가 없습니다.
알 수 없는 표시 키는 무시해야 합니다. x-ui 키 추가는 하위 호환 변경입니다.
{
"type": "object",
"required": ["prompt", "duration_seconds"],
"additionalProperties": false,
"properties": {
"prompt": {
"type": "string",
"minLength": 1,
"description": "Describes the scene and its motion.",
"x-ui": { "widget": "textarea", "order": 100, "primary": true, "rows": 4 }
},
"duration_seconds": {
"type": "integer",
"enum": [5, 8, 10],
"description": "Output duration in seconds.",
"x-ui": { "widget": "radio", "order": 90, "unit": "s", "affects_price": true }
}
},
"x-pricing": { "variantFields": ["duration_seconds"], "billingMode": "variant_matrix" }
}모든 description은 영어 설명이며 필드 도움말로 그대로 표시할 수 있습니다.
x-ui.affects_price: true는 필드 변경 후 UI가 견적을 갱신해야 함을 뜻합니다. 가격 공식이 아니며 카탈로그의 pricing이나 quantityField를 대체하지 않습니다. 루트 x-pricing은 같은 정보의 서버 측 표현입니다. variantFields는 가격 구간을 선택하는 필드이며 항상 affects_price: true 필드의 부분집합입니다. billingMode는 과금 수량 계산 방식을 나타냅니다. 모두 힌트이며 기준 금액은 카탈로그·견적·작업이 반환한 금액입니다. pricing의 구간 표현은 가격 읽기를 참고하세요.
조건부 필드
조건은 모두 루트에서 정확히 두 형식만 사용합니다.
{
"anyOf": [{ "required": ["image_url"] }, { "required": ["image_urls"] }],
"allOf": [
{ "if": { "required": ["last_image_url"] }, "then": { "required": ["image_url"] } },
{ "if": { "properties": { "resolution": { "const": "4k" } } }, "then": { "required": ["seed"] } }
]
}anyOf 분기는 required만 포함하며 ‘이 중 하나 이상 제공’입니다. allOf 분기는 if → then 하나입니다. if는 required 또는 properties.<field>.const로 조건을 판단하고 then은 required만 선언합니다. ‘A를 제공하면 B도 제공’이라는 뜻입니다.
oneOf, not, dependentSchemas, dependentRequired는 모델 inputSchema에 나오지 않습니다. 제약은 표현할 수 있지만 폼으로 렌더링하기 어려워 제출 후 설명하기 힘든 400으로만 드러나기 때문입니다. 위 두 형식을 구현하면 모든 조건부 엔드포인트를 처리할 수 있습니다.
비동기 수명 주기
queued -> running -> succeeded
-> failed
-> expiredcreateTask는 Spicy 작업 ID를 반환합니다. recordInfo로 조회하거나 서명된 Spicy webhook을 받으세요. queued와 running은 진행 상태이고 나머지는 종료 상태입니다. 과거 canceled 기록은 호환성을 위해 읽을 수 있지만 새 작업에 취소 동작은 없습니다. 상태 기준은 비동기 작업입니다.
모델 내부에서 알 수 없는 진행 상태는 알려진 종료 상태나 절대 플랫폼 기한에 도달할 때까지 running으로 변환합니다. 승인 여부가 불확실한 비멱등 제출은 무작정 반복하지 않아 중복 생성·과금을 방지합니다.
공통 응답과 오류
모든 네이티브 JSON API(/api/v1)는 공통 응답 형식을 사용하며 /v1과 /v1beta 호환 엔드포인트는 각 프로토콜 형식을 사용합니다.
{
"code": 200,
"msg": "success",
"data": {},
"request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}동기 실패 시 data는 없습니다. 변할 수 있는 msg가 아닌 code로 분기하고 지원 문의에 request_id를 사용하세요. 생성 후 실패는 data.state: "failed"와 안정적인 errorCode를 사용합니다. errorMessage는 사람이 읽는 설명입니다. 모델 서비스가 구체적 이유를 반환하면 내부 이름·주소·계정 정보를 제거한 영어 이유를 제공합니다. 그 외에는 오류 언어에 맞는 플랫폼 메시지입니다. 분기는 errorMessage가 아닌 errorCode로 하세요.
결과와 다운로드
성공 작업은 output.assets[]에 파일을 나열하며 준비된 결과물에는 이미 다운로드 링크가 있습니다.
{
"assets": [
{
"key": "tasks/2026/08/31/job_01k3m8x9q2z4v7n5p6r8s0t1w3/asset_01.mp4",
"url": "https://example.r2.cloudflarestorage.com/results/asset_01.mp4?X-Amz-Signature=SIGNATURE_FROM_RESPONSE",
"expiresAt": "2026-08-31T10:20:00Z",
"mime": "video/mp4",
"durationSeconds": 8,
"bytes": 1234567
}
]
}API 키 없이 url을 직접 다운로드하세요. 일반적으로 20분 유효하며 결과가 보관되는 동안(최대 14일) 작업을 다시 읽어 새 링크를 얻습니다. 파일 저장 중에는 pending: true이고 url이 없습니다. 영구적으로 저장 실패하면 unavailable: true입니다. key는 선택적인 download-url 엔드포인트의 파일 식별자이며 직접 다운로드에는 필요하지 않습니다. 모든 링크는 SpicyAPI 자체 저장소를 가리킵니다.
고객 과금
카탈로그의 pricing, startingPrice, quantityField와 작업의 estimatedCost / cost는 고객 가격만 설명합니다. 금액은 십진 USD 문자열입니다. 내부 사업 정보는 공개 계약 범위 밖이며 카탈로그, 작업, webhook이나 내보낸 로그에 나오지 않습니다.
호환성과 지원 종료
새 선택 필드, 무시 가능한 새 응답 필드, 알 수 없는 x-ui 힌트가 추가되어도 클라이언트가 계속 작동해야 합니다.
새 필수 필드, 열거값 제거, 의미·유형 변경, 한도 축소와 공개 모델 ID 변경은 새 모델 버전 또는 사전 안내된 지원 종료 기간과 함께 적용됩니다. 공개 ID는 변경하지 않으며 이전은 호환 별칭이나 명시적 리디렉션을 사용합니다.
카탈로그 캐시에 따라 인증된 카탈로그를 캐시하세요. 영구 스키마 사본을 두거나 최신 카탈로그에 호출 가능한 항목이 없다고 정적 페이지로 대체하지 마세요.

