AI 영상 출력용 JSON 스키마: 복사해 쓰는 템플릿 5개

Sume에서 AI 영상 출력에 쓸 JSON Schema 템플릿입니다. 영상 하나, 영상과 게시 문구, 포스터, 화면 비율, 자막 큐를 모두 strict 부분집합 안에서 복사해 쓸 수 있습니다.

읽는 시간 5분Sume
전체 글

Sume에서 AI 영상 출력용 JSON Schema는 Format 실행에 바인딩하는 output_schema입니다. 끝난 실행의 output이 그 형태로 돌아오며, 각 미디어 파일은 { "$ref": "SumeMediaFile#" }로 타입이 지정되고 실행이 만든 미디어와 대조됩니다. 아래 템플릿 5개는 Sume의 strict 부분집합에 맞으므로 제출 시 검사를 통과합니다.

각 템플릿은 2026-09-27에 확인한 Sume 구조화 출력 (영문) 문서의 규칙을 따릅니다. POST /v1/formats/{handle}/{slug}/runs에 output_schema로 보내거나, OpenAI 형태의 별칭인 response_format에 "type": "json_schema"와 함께 json_schema 아래로 중첩해 보내세요. 둘 다 보내면 400 invalid_request입니다. 규칙은 Sume Format 구조화 출력에서 설명하고, 이 글은 복사해 쓸 스키마를 제공합니다.

완성된 영상 하나를 받으려면 어떻게 하나요?

쓸모 있는 가장 작은 스키마로, 필수 미디어 파일 하나를 받습니다. "primary_output_key": "video"와 함께 보내면 영수증의 primary_output_url이 그 파일의 URL이 됩니다. SumeMediaFile은 이미지, 영상, 오디오, 파일을 모두 다루므로 키 이름만으로 영상이 보장되지는 않습니다. 쓸 때는 type을 확인하세요. 미디어를 하나도 생성하지 않은 실행은 이 키를 채울 수 없으므로, API에서는 빈 output으로 completed가 되는 대신 failed로 끝납니다.

{
  "name": "acme/video-only/v1",
  "strict": true,
  "schema": {
    "type": "object",
    "additionalProperties": false,
    "required": ["video"],
    "properties": {
      "video": { "$ref": "SumeMediaFile#" }
    }
  }
}

영상과 게시 문구를 함께 받으려면 어떻게 하나요?

문구 필드는 일부러 nullable로 둡니다. 실행이 객체를 직접 제출하지 않으면, projection 패스가 실행이 생성한 미디어와 마무리 텍스트라는 두 가지 사실만으로 객체를 채웁니다. 이 패스는 input이나 instruction을 전혀 보지 못하므로, 브리프에 기대는 문장은 이 경로에서 null로 돌아올 수 있습니다. hashtags에는 minItems가 없으므로 빈 목록도 유효합니다. maxItems와 pattern은 직접 쓴 다른 모든 키워드처럼 강제됩니다. 열한 번째 해시태그나 #이 없는 해시태그는 스키마를 만족하지 않습니다.

{
  "name": "acme/video-with-copy/v1",
  "strict": true,
  "schema": {
    "type": "object",
    "additionalProperties": false,
    "required": ["video", "title", "caption", "hashtags"],
    "properties": {
      "video": { "$ref": "SumeMediaFile#" },
      "title": { "type": ["string", "null"] },
      "caption": {
        "type": ["string", "null"],
        "description": "Post caption written for the video"
      },
      "hashtags": {
        "type": "array",
        "maxItems": 10,
        "items": { "type": "string", "pattern": "^#[A-Za-z0-9_]+$" }
      }
    }
  }
}

없을 수도 있는 포스터 프레임은 어떻게 요청하나요?

없을 수도 있는 미디어 파일은 SumeMediaFile#과 null의 anyOf로 표현합니다. 제약은 anyOf 옆이 아니라 분기 안에 넣으세요. anyOf와 $ref의 형제 키워드는 아무 의미가 없습니다. URL 게이트는 실행이 생성한 미디어만 통과시키므로, 실행이 업로드만 한 파일은 projection을 실패시킵니다. 업로드한 파일은 스키마에 넣지 마세요.

{
  "name": "acme/video-with-poster/v1",
  "strict": true,
  "schema": {
    "type": "object",
    "additionalProperties": false,
    "required": ["video", "poster"],
    "properties": {
      "video": { "$ref": "SumeMediaFile#" },
      "poster": {
        "anyOf": [{ "$ref": "SumeMediaFile#" }, { "type": "null" }]
      }
    }
  }
}

실행 한 번으로 여러 화면 비율을 받으려면 어떻게 하나요?

비율마다 키를 하나씩 두고, 정의는 $defs로 공유하세요. $defs는 스키마 루트에 있어야 합니다. 스키마는 끝난 실행을 어떻게 되읽을지만 정하므로, 세 가지 비율은 instruction에서 요청하세요. "primary_output_key": "vertical"과 함께 쓰면, 스키마는 만족했지만 그 키를 null로 남긴 실행은 primary_output_missing과 함께 failed로 끝나고, 나머지 두 키는 null이어도 됩니다.

{
  "name": "acme/aspect-set/v1",
  "strict": true,
  "schema": {
    "type": "object",
    "additionalProperties": false,
    "required": ["vertical", "square", "landscape"],
    "properties": {
      "vertical": { "$ref": "#/$defs/maybe_video" },
      "square": { "$ref": "#/$defs/maybe_video" },
      "landscape": { "$ref": "#/$defs/maybe_video" }
    },
    "$defs": {
      "maybe_video": {
        "anyOf": [{ "$ref": "SumeMediaFile#" }, { "type": "null" }]
      }
    }
  }
}

영상과 함께 시간이 표시된 자막 줄을 받으려면 어떻게 하나요?

배열 안과 $defs 안의 객체에도 additionalProperties: false가 필요합니다. 무엇이 검사되는지 알아 두세요. URL, 미디어 파일의 duration_ms(파일에 기록된 길이와 10% 이내), 그리고 형태입니다. 자막 텍스트와 큐 시간은 실행이 자기 작업에 대해 스스로 밝힌 내용으로, 실행이 보고한 것에 근거하지만 파일과 대조해 검증되지는 않습니다.

{
  "name": "acme/video-with-cues/v1",
  "strict": true,
  "schema": {
    "type": "object",
    "additionalProperties": false,
    "required": ["video", "cues"],
    "properties": {
      "video": { "$ref": "SumeMediaFile#" },
      "cues": { "type": "array", "items": { "$ref": "#/$defs/cue" } }
    },
    "$defs": {
      "cue": {
        "type": "object",
        "additionalProperties": false,
        "required": ["start_ms", "end_ms", "text"],
        "properties": {
          "start_ms": { "type": "integer", "minimum": 0 },
          "end_ms": { "type": "integer", "minimum": 0 },
          "text": { "type": "string" }
        }
      }
    }
  }
}

어떤 템플릿에서 시작해야 하나요?

레코드에 필요한 것을 기준으로 고른 뒤 키 이름을 바꾸세요. 수정한 스키마가 strict 부분집합을 벗어나면 생성 요청은 400 output_schema_invalid로 실패하고 아무것도 청구되지 않습니다. 위반 항목 가이드가 details.violations[]의 규칙마다 고치는 방법을 짚어 줍니다.

위 템플릿 5개는 모두 구조화 출력 (영문)의 strict 부분집합 안에 있습니다(2026-09-27 확인).
템플릿필수 키null 또는 빈 값 허용그 밖에 쓴 키워드
완성된 영상 하나video없음없음
영상과 게시 문구video, title, caption, hashtagstitle과 caption은 null 가능, hashtags는 [] 가능description, maxItems, pattern
선택적 포스터 프레임video, posterposter는 null 가능anyOf
여러 화면 비율vertical, square, landscape셋 다 null 가능. 단, vertical이 primary_output_key일 때 null이면 실행이 실패함$defs, anyOf
시간이 표시된 자막 큐video, cuescues는 [] 가능$defs, minimum

끝난 실행이 스키마를 채우지 못하면 어떻게 되나요?

API에서는 실행이 실패합니다. status는 failed가 되고, output_error가 이유를 알려 주며, artifacts[]에는 실행이 만든 모든 파일이 그대로 나열됩니다. 코드별 설명은 Sume Format 실행 실패 코드에 있습니다.

출처

관련 글

포맷 카테고리의 다른 글

포맷 글 전체 보기

작성자 Sume