Home > Dev > Docs
Home / Pricing / Docs / Apps

비디오스튜 개발자 문서

요청 형식 주의사항 POST 요청 시 Content-Type: application/json 헤더와 함께 JSON body를 그대로 전달하는 방식을 권장합니다. application/x-www-form-urlencoded를 사용할 경우에는 파라미터를 JSON으로 직렬화한 뒤 payload 필드에 담아 전송하십시오. 예: payload={"apiKey":"...","secret":"..."}

Automation API

편집 화면 없이 동영상을 자동으로 생성·추출하는 API입니다. 토큰 노출 방지를 위해 반드시 백엔드에서만 호출하십시오.

POST https://videostew.com/api/automations

프로젝트 생성과 추출을 동시에 자동화합니다. 완료된 최종 결과는 webhookUrl 또는 앱 설정의 Export Webhook으로 POST 전달됩니다. 이 방법으로 생성된 프로젝트는 추출 이후 일주일 후 자동으로 삭제됩니다.

인증 헤더

헤더 필수 설명
Authorization 계정 설정 > API 토큰에서 복사한 토큰. Bearer Qjky6mFiMkRn... 형식
x-nonce 각 요청에 대한 유니크한 값 (중복 요청 구분용)

바디 파라미터

파라미터 필수 타입 설명
injector object 데이터 주입/변형 명세. 아래 Injector 섹션 참고
dictionary object TTS/STT 텍스트 치환 규칙. 아래 dictionary 섹션 참고
baseProjectId string 특정 프로젝트를 템플릿으로 사용할 경우의 projectId. 같은 스페이스이거나 public 상태여야 함
spaceId int 대상 워크스페이스 고유번호. 0이면 기본 워크스페이스
type string 추출 파일 형식. mp4 | jpg
webhookUrl string 완료 시 결과를 전달할 URL
webhookType string webhook 전달 방식. form | json
webhookHeader string webhook 커스텀 헤더. 헤더명: 값 형식. 예: x-api-key: abc123

호출 예시

curl -X POST "https://videostew.com/api/automations" \
  -H "Authorization: Bearer {{bearerToken}}" \
  -H "x-nonce: $RANDOM" \
  -H "Content-Type: application/json" \
  -d '{
    "baseProjectId": "88282f69vmqbqr9",
    "injector": {
      "wizard": {
        "source": "url",
        "sourceContent": "https://doo39oi115k60.cloudfront.net/wizard-url-example/"
      }
    }
  }'

응답 예시

{
  "status": "done",
  "result": {
    "projectId": "abc123..."
  }
}

처리 결과 확인: https://videostew.com/v/{projectId} 에 접속했을 때 "추출중입니다" 메시지가 표시되면 렌더링이 정상 진행 중입니다. 약 5분 후 같은 URL에서 완성된 영상을 확인할 수 있습니다. 완료 이벤트를 코드로 받으려면 webhookUrl을 지정하세요.

Webhook 응답 (추출 완료 시)

{
  "status": "done",
  "projectId": "abc123...",
  "size": "1080x1920",
  "type": "mp4",
  "link": "https://cdn.videostew.com/projects/..."
}

Injector 세부 옵션

데이터를 주입하는 방법으로 wizard, data를 제공하며, 각각은 배타적이므로 한 번에 한가지 방식만 사용할 수 있습니다.

injector.wizard

텍스트 또는 URL을 넘기면 AI가 분석해 동영상을 자동으로 만들어줍니다. 세부적인 제어는 어렵지만, 가장 간단하게 동영상을 생성할 수 있는 방법입니다.

파라미터 설명
source 소스 타입. text | url
sourceContent source에 대응하는 값. text면 HTML/plain text, url이면 URL 문자열
title 프로젝트 제목
language 프로젝트 언어. 예: ko, en, ja
opts.replace AI가 교체할 슬라이드 범위. body=본문만 교체, 인트로/아웃트로는 템플릿 그대로 유지(반복 사용하는 고정 애니메이션·엔딩에 적합). headbody=AI가 소제목을 자동 생성하며 소제목+본문 교체, 인트로/아웃트로 유지. all=인트로/아웃트로 포함 전체 교체
opts.visual 비주얼 소스 방식. stock-mixed/stock-video/stock-image=비디오스튜 스톡 라이브러리에서 맥락에 맞는 리소스를 자동 매칭(각각 혼합/비디오만/이미지만). ai-image=AI로 이미지 생성. none=비주얼 없음(원본 URL에 이미지가 풍부할 때 적합)
opts.autoLineBreak y로 설정하면 텍스트를 줄 단위로 분리해, 한 줄씩 등장하는 텍스트 애니메이션이 의도대로 동작합니다. 대부분의 템플릿이 이 애니메이션을 기본으로 사용하므로 y 권장
opts.visualStyle 비주얼 스타일. illust=디지털아트, photo=실사, flat-vector=벡터, editorial-cartoon=만평, editorial-illust=신문 일러스트, silhouette=실루엣. 또는 "수묵화 스타일로 그려줘" 처럼 직접 프롬프트를 입력해 원하는 스타일을 지정
adjust.duration 목표 분량. keep=원본 유지, 30s | 1m | 3m | 10m | 20m
adjust.structure 구조. keep=원본, body=본문만, headbody=소제목+내용 형식
adjust.style 스크립트 스타일. keep=원본 유지, colloquial=팟캐스트 같은 대화형, news=뉴스 방송처럼 공식적·객관적, info=정보 전달에 최적화된 명확·간결한 스타일, insight=인사이트와 분석을 강조하는 심층적 스타일, essay=서술적·사색적 에세이 톤, casual=친근하고 편안한 일상 대화 스타일. 또는 "시청자에게 말 걸듯 친근하게, 유머도 살짝 섞어줘" 처럼 직접 프롬프트를 입력해 원하는 스타일을 지정

adjust의 모든 키가 keep이면 원본 글을 AI로 다듬는 과정 없이 원문 그대로 사용합니다.

{
  "wizard": {
    "source": "url",
    "sourceContent": "https://doo39oi115k60.cloudfront.net/wizard-url-example/",
    "language": "ko",
    "opts": {
      "replace": "all",
      "visual": "ai-image",
      "visualStyle": "illust",
      "autoLineBreak": "y"
    },
    "adjust": {
      "duration": "1m",
      "structure": "headbody",
      "style": "news"
    }
  }
}

injector.data

프로젝트/슬라이드/요소 구조를 직접 지정합니다. 영상을 어떻게 만들 것인지 모든 것을 직접 구성할 때 사용합니다. 기존 요소와 일치하면 대체, 없으면 신규 생성합니다. 변경이 필요한 키만 지정하면 되며, 지정하지 않은 값은 기존 프로젝트의 값을 유지합니다.

data 키

최상위에 지정한 bgm은 slides 배열 전체에 기본값으로 적용됩니다. 각 슬라이드별 지정이 있으면 그 값을 더 우선시합니다.

설명
title 프로젝트 제목
language 프로젝트 언어. 예: ko, en
bgm 프로젝트 BGM 파일 URL
slides 슬라이드 배열

data.slides[] 키

설명
label 슬라이드 식별 레이블(기본 베이스 프로젝트내의 슬라이드 라벨기준으로 매칭). 같은 label을 여러 번 지정하면 해당 템플릿 슬라이드를 복제해 슬라이드 수를 늘릴 수 있습니다. 예: main 라벨을 3번 쓰면 main 슬라이드가 3개 생성. 라벨값은 편집화면에서 하단의 슬라이드 패널에서 확인할 수 있습니다.
narration 슬라이드 나레이션. 텍스트를 입력하면 템플릿에 설정된 AI 목소리로 읽어줍니다. 직접 녹음한 오디오를 쓰려면 공개 URL을 입력하세요
sound 슬라이드 효과음 URL
bgm 이 슬라이드에만 적용할 BGM URL. 최상위 bgm보다 우선
text 텍스트 요소 내용. 단순 문자열이면 슬라이드의 첫 번째 텍스트 요소에 적용. 슬라이드에 텍스트 요소가 여러 개 있을 때 각 요소를 정확히 타겟팅하려면 { "label": "요소라벨", "content": "내용" } 객체 형태로 배열 지정(라벨은 템플릿에서 설정한 요소 라벨 기준). 빈 문자열이면 요소 삭제. elements 배열 방식은 지원하지 않습니다.
image 이미지 요소 libraryId. 배열로 여러 개 지정 가능
video 비디오 요소 libraryId. 배열로 여러 개 지정 가능

참고: URL을 지정하는 모든 필드(image, video, sound, bgm, narration 등)는 공개(public) 접근 가능한 주소여야 하며, 크롬 브라우저 기준의 표준 파일 형식이어야 합니다.

예시 1 — 텍스트·이미지 치환 + TTS 나레이션

{
  "data": {
    "language": "ko",
    "bgm": "https://example.com/bgm.mp3",  // 모든 슬라이드에 공통 적용
    "slides": [
      {
        "label": "title",                   // 베이스 프로젝트의 슬라이드 레이블로 매칭
        "text": "오늘의 뉴스 제목",           // 템플릿의 텍스트 요소를 이 내용으로 교체
        "image": "https://doo39oi115k60.cloudfront.net/wizard-url-example/01.webp",
        "narration": "오늘의 뉴스를 전해드립니다."  // 문자열이면 TTS로 생성(베이스 프로젝트의 나레이션 속성 따름)
      },
      {
        "label": "body",
        "text": "본문 내용입니다.",
        "image": "https://doo39oi115k60.cloudfront.net/wizard-url-example/02.webp"
      },
      {
        "label": "outro",
        "text": ""                          // 빈 문자열이면 해당 텍스트 요소 삭제
      }
    ]
  }
}

예시 2 — 라벨로 요소 타겟팅

템플릿에 텍스트 요소가 여러 개 있을 때, { label, content } 형태로 어떤 요소에 무엇을 넣을지 정확히 지정할 수 있습니다. 단, 이 방식은 Videostew 편집 화면에서 각 텍스트 요소에 미리 라벨을 붙여두어야 동작합니다. 라벨이 없는 요소는 타겟팅할 수 없습니다. 예를 들어 상단 요소에 title, 하단 AI 보이스용 요소에 voicetext라고 라벨을 붙여둔 템플릿이라면 아래처럼 각각 제어할 수 있습니다.

{
  "data": {
    "slides": [
      {
        "label": "main",
        "text": [
          { "label": "title", "content": "이거 진짜 될까?" },       // 화면 상단 타이틀 요소
          { "label": "voicetext", "content": "이거 진짜 될까" }     // AI 보이스가 읽을 자막 요소
        ]
      }
    ]
  }
}

예시 3 — 녹음 파일 나레이션 + 슬라이드별 비디오

{
  "data": {
    "slides": [
      {
        "label": "intro",
        "narration": "https://doo39oi115k60.cloudfront.net/wizard-url-example/narration1.mp3", // 직접 녹음/합성한 오디오 파일
        "video": "https://doo39oi115k60.cloudfront.net/wizard-url-example/video1.mp4"
      },
      {
        "label": "body",
        "narration": "https://doo39oi115k60.cloudfront.net/wizard-url-example/narration2.mp3", 
        "video": "https://doo39oi115k60.cloudfront.net/wizard-url-example/video2.mp4",
        "bgm": "https://example.com/this-slide-only.mp3"  // 이 슬라이드만 다른 BGM
      }
    ]
  }
}
상세 설정

단순한 키 대칭으로 표현하기 힘든 상세한 세부 제어가 필요할 때 사용합니다(위치 혹은 복수의 갯수일 때). 아래는 사용 가능한 키의 전체 목록이며, 실제 요청에는 필요한 것만 포함하세요.

color 포맷: [[R, G, B, A], degree] — R/G/B는 0–255, A는 0–1 (불투명도), degree는 그라데이션 각도 (단색이면 0).

{
  "data": {
    "title": "프로젝트 제목",
    "language": "ko",
    "slides": [
      {
        "trans": {
          "type": "fade",       // auto | fade | flip-ltr | flip-ttb | cube-ltr | cube-rtl | reveal-ltr | reveal-rtl
          "durationTime": 0.3
        },
        "narration": {
          "type": "voice",      // voice
          "libraryId": "https://doo39oi115k60.cloudfront.net/wizard-url-example/narration1.mp3",
          "content": "", // TTS 텍스트 (type이 tts일 때),
          "volume": 1,
          "speed": 1.1,
          "trimStart": 0,
          "trimEnd": 0
        },
        "glb": {
          "bgmLibraryId": "https://example.com/bgm.mp3",
          "bgmVolume": 0.9,
          "bgmSpeed": 1,
          "soundLibraryId": "https://example.com/sfx.mp3",
          "soundVolume": 1,
          "soundEvery": true,
          "soundFit": false,
          "backgroundColor": [[0, 0, 0, 1], 0],
          "bgBlr": false,
          "bgBlrB": 0.4
        },
        "elements": [
          {
            "type": "text",
            "content": "텍스트 내용",
            "rect": {
              "top": 800, "left": 40, "width": 1000, "height": 200,
              "opacity": 1
            },
            "custom": {
              "fontSize": 48,
              "color": [[255, 255, 255, 1], 0],
              "align": "center",          // left | center | right
              "valign": "v_bottom",       // top | middle | bottom | v_top | v_bottom
              "lineHeight": 1.2,
              "raType": "block",          // notset | block | inline | outline | textShadow
              "raColor": [[0, 0, 0, 1], 0],
              "enabledTts": true,
              "splitLine": "1l",          // "" | 1l | 2l | p
              "splitLineType": "replace"  // replace | add
            }
          },
          {
            "type": "image",
            "libraryId": "https://doo39oi115k60.cloudfront.net/wizard-url-example/01.webp",
            "rect": {
              "top": 0, "left": 0, "width": 1080, "height": 1920,
              "opacity": 1,
              "innerType": "cover",       // cover | contain | fill
              "innerPosition": "50% 30%"  // CSS position 형식, 이미지 포커스 위치
            }
          },
          {
            "type": "video",
            "libraryId": "https://doo39oi115k60.cloudfront.net/wizard-url-example/video1.mp4",
            "rect": {
              "top": 0, "left": 0, "width": 1080, "height": 1080,
              "innerType": "cover",
              "innerPosition": "50% 50%"
            },
            "custom": {
              "trimStart": 0,
              "trimEnd": 10,
              "speed": 1,
              "volume": 1,
              "loop": 9999    // 0 = 반복 안함, 9999 = 무한 반복
            }
          },
          {
            "type": "shape",
            "libraryId": "shape-library-id",
            "rect": {
              "top": 0, "left": 0, "width": 200, "height": 200
            },
            "custom": {
              "color": [[255, 100, 0, 1], 0]
            }
          }
        ]
      }
    ]
  }
}

dictionary

TTS/STT 시 적용할 텍스트 치환 규칙입니다. injector와 함께 바디 최상위에 전달합니다. 스페이스 딕셔너리와 병합되며 여기서 지정한 값이 우선합니다. 영역당 최대 100개 항목.

설명
tts AI 보이스가 텍스트를 읽을 때 적용. 잘못 발음되는 단어를 올바른 발음으로 강제 지정
stt 음성을 텍스트로 변환(자막 생성)할 때 적용. STT가 잘못 인식하는 단어를 올바른 표기로 강제 교정
trans 번역 후처리 시 적용
{
  "injector": {
    "wizard": { "source": "url", "sourceContent": "https://doo39oi115k60.cloudfront.net/wizard-url-example/" }
  },
  "dictionary": {
    "tts": [
      { "i": "3D", "o": "쓰리디" },       // "삼디"로 읽히는 걸 방지
      { "i": "AI", "o": "에이아이" }       // "아이"로 읽히는 걸 방지
    ],
    "stt": [
      { "i": "video studio", "o": "videostew" },   // STT가 잘못 인식한 표기를 교정
      { "i": "비디오 스튜", "o": "비디오스튜" }     // 띄어쓰기 오인식 교정
    ]
  }
}

기타 API

GET https://videostew.com/api/spaces — 워크스페이스 목록 조회

curl -X GET "https://videostew.com/api/spaces" \
  -H "Authorization: Bearer {{bearerToken}}" \
  -H "x-nonce: $RANDOM"

GET https://videostew.com/api/projects — 프로젝트 목록 조회

파라미터 타입 설명
spaceId int 대상 워크스페이스 고유번호. 0이면 기본 워크스페이스
projectIds string 콤마로 구분된 프로젝트 ID 목록
folderId int 폴더 고유번호. 기본값(루트) 1000000
status string public | enabled | secret. trash는 삭제된 상태
limit int 페이지당 항목수
page int 페이지 번호
title string 제목 검색
tags string 태그 검색
curl -X GET "https://videostew.com/api/projects?spaceId=0&limit=20&page=1" \
  -H "Authorization: Bearer {{bearerToken}}" \
  -H "x-nonce: $RANDOM"

GET https://videostew.com/api/projects/:projectId — 단일 프로젝트 조회

curl -X GET "https://videostew.com/api/projects/PROJECT_ID" \
  -H "Authorization: Bearer {{bearerToken}}" \
  -H "x-nonce: $RANDOM"

쿼리 파라미터: includeSlides=true (슬라이드 상세 포함, 대용량)

GET https://videostew.com/api/exports — 추출 목록 조회

파라미터 타입 설명
spaceId int 대상 워크스페이스 고유번호. 0이면 기본 워크스페이스
projectIds string 콤마로 구분된 프로젝트 ID 목록
projectId string 특정 프로젝트의 추출만 조회
type string mp4 | jpg
limit int 페이지당 항목수
page int 페이지 번호
curl -X GET "https://videostew.com/api/exports?projectId=PROJECT_ID&limit=20" \
  -H "Authorization: Bearer {{bearerToken}}" \
  -H "x-nonce: $RANDOM"

GET https://videostew.com/api/exports/:projectId/:exportId — 단일 추출 조회

curl -X GET "https://videostew.com/api/exports/PROJECT_ID/EXPORT_ID" \
  -H "Authorization: Bearer {{bearerToken}}" \
  -H "x-nonce: $RANDOM"

POST https://videostew.com/api/exports/:projectId — 추출 요청

파라미터 타입 설명
type string mp4 | jpg
webhookUrl string 완료 시 결과를 받을 URL
webhookType string form | json
webhookHeader string webhook 커스텀 헤더. 헤더명: 값 형식. 예: x-api-key: abc123
curl -X POST "https://videostew.com/api/exports/PROJECT_ID" \
  -H "Authorization: Bearer {{bearerToken}}" \
  -H "x-nonce: $RANDOM" \
  -H "Content-Type: application/json" \
  -d '{"type":"mp4","webhookUrl":"https://your-server.com/webhook"}'

응답:

{
  "status": "done",
  "result": {
    "id": "e-19",
    "projectId": "...",
    "status": "generate",
    "type": "mp4"
  }
}

Webhook 응답 (추출 완료 시):

{
  "status": "done",
  "projectId": "...",
  "size": "1280x720",
  "type": "mp4",
  "link": "https://cdn.videostew.com/projects/..."
}

SDK

SDK curl 예시에 인증정보를 자동으로 채우려면 앱 관리 페이지에서 앱을 먼저 발급하세요.

자사의 웹사이트에서 자사의 고객들에게 비디오스튜의 편집화면만 제공할 때 사용합니다.

인증 (엑세스 토큰 발급/만료)

SDK를 사용할 때는 각 사용자마다 개별 엑세스 토큰을 발급해야 합니다. 토큰은 마지막 사용 이후 1개월 간 유효하며, 재사용 시 자동 연장됩니다. 401 Token is invalid 응답이 오면 새 토큰을 발급해 fallback 처리하세요.

!! secret 키 노출 방지를 위해 반드시 백엔드에서만 요청하십시오.

POST https://videostew.com/auth/access-token — 엑세스 토큰 발급

파라미터 필수 타입 설명
apiKey string 발급받은 앱의 ApiKey
secret string 발급받은 앱의 시크릿 키
uniqueId any 자사 플랫폼에서 사용하는 유저의 고유번호
language string uniqueId 신규 생성 시 언어 강제 지정. 예: ko, en
curl -X POST "https://videostew.com/auth/access-token" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "{{apiKey}}",
    "secret": "{{secret}}",
    "uniqueId": "user_123"
  }'

응답:

{
  "status": "done",
  "apiKey": "abc1de2fg3...",
  "token": "Qjky6mFiMkRnOmExYj..."
}

POST https://videostew.com/auth/revoke-access-token — 엑세스 토큰 만료 (선택)

로그아웃 등 모든 활동 종료 시 해당 유저의 토큰을 강제 만료합니다. 토큰은 1회성이 아니므로 강제 삭제 시 사용 중인 다른 탭에서 문제가 발생할 수 있습니다. 사용자가 탈퇴 등으로 확실히 그만두는 시점에서 호출하시면 됩니다.

curl -X POST "https://videostew.com/auth/revoke-access-token" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "{{apiKey}}",
    "secret": "{{secret}}",
    "uniqueId": "user_123"
  }'

편집기 호출

videostewSDK.open(options)

버튼 클릭 등의 이벤트에서 편집기를 모달로 엽니다.

<script src="https://cdn.videostew.com/web/sdk/sdk-latest.js"></script>
<script>
	videostewSDK.open({
		token: "Qjky6mFiMkRnOmEx...", // /auth/access-token 응답의 token 값
		projectId: "...",     // 수정할 프로젝트 ID (없으면 신규 생성)
		// baseProjectId: "...",  // 특정 프로젝트를 템플릿으로 사용(신규 생성시)
		// language: "ko",        // 프로젝트 및 UI 언어 설정
		// injector: { ... },     // 데이터 주입/변형 명세
		// dictionary: { ... },   // TTS/STT 텍스트 치환 규칙
		callbackFunc: function(result) {
			// 사용자가 [Done]을 눌렀을 때 호출
			console.log(result.projectId);
			// result: { projectId, thumbnailUrl, spaceId, width, height, title, status, slideCount, savedAt }
		},
		eventFunc: function(projectId, eventName) {
			// 편집 화면 내 이벤트 발생 시 호출
			// eventName: openPreview, saveProject, openDownload,
			//            requestExportPng, requestExportMp4, exportedPng, exportedMp4,
			//            downloadPng, downloadMp4, openProjectInfo, updateProjectInfo
		},
		errorFunc: function(errorMessage) {
			// 토큰 만료 시 호출 → 새 토큰 발급 후 재시도 처리
			// errorMessage: "Token is invalid"
		}
	});
</script>
옵션 필수 설명
token /auth/access-token 응답의 token 값. 예: Qjky6mFiMkRn...
apiKey 레거시 방식(raw token) 사용 시에만 필요. 신규 방식은 생략
projectId 수정할 프로젝트 ID. 없으면 신규 생성
baseProjectId 템플릿 프로젝트 ID. 같은 스페이스이거나 public 상태여야 함
language 프로젝트 및 UI 언어. 미지정 시 기본 en
injector 데이터 주입/변형 명세. Injector 섹션 참고
dictionary TTS/STT 텍스트 치환 규칙. dictionary 섹션 참고
callbackFunc function(result) — [Done] 버튼 클릭 시 호출, 앱 설정에 Done Webhook이 지정된 경우 이 설정은 무시됩니다.
eventFunc function(projectId, eventName) — 편집 화면 내 이벤트 발생 시 호출
errorFunc function(errorMessage) — 토큰 만료 시 호출

videostewSDK.save()

편집 화면 상태를 저장합니다. 유저가 [Save] 버튼을 누른 것과 동일하므로 특별한 경우가 아니면 호출할 필요가 없습니다.

videostewSDK.save();

videostewSDK.done()

편집 내용을 저장하고 callbackFunc 또는 Done Webhook으로 결과를 전달합니다.

videostewSDK.done();

videostewSDK.cancel(force?)

편집기를 닫습니다. 저장되지 않은 내용이 있으면 확인 팝업이 표시됩니다.

videostewSDK.cancel();
// videostewSDK.cancel(true); // 강제 닫기
[중단]