동영상 생성
POST /v1/videos · GET /v1/videos/{id} · DELETE /v1/videos/{id}
텍스트 프롬프트로 짧은 동영상을 생성합니다. 참조 프레임(첫/마지막)으로 화면을 제어할 수도 있습니다. 업계 표준 create + poll 형태의 비동기 작업 API입니다: POST /v1/videos가 약 2초 만에 작업을 만들고, 완료될 때까지 폴링하며, Prefer: wait 헤더를 쓰면 빠른 생성은 한 번의 동기 호출로 끝납니다. Seedance 모델, 하나의 API 키, 과금은 다른 엔드포인트와 동일합니다.
동영상 API는 현재 제한 프리뷰(초대제 테스트)입니다. 모델은 카탈로그와 가격에 표시되지만, 작업을 생성하려면 워크스페이스가 허용 목록에 있어야 합니다 — 활성화하려면 저희에게 문의하세요.
엔드포인트와 작업 수명 주기
하나의 작업 리소스, 네 가지 조작. 작업은 queued → in_progress → 최종 상태(completed, failed 또는 cancelled)로 진행됩니다. 생성 응답에는 status_url / cancel_url 링크가 포함되어 URL을 직접 조립할 필요가 없습니다.
| 엔드포인트 | 설명 |
|---|---|
POST /v1/videos | 생성 작업을 만듭니다. 약 2초 만에 작업 객체(status queued)와 폴링 링크를 반환합니다. |
GET /v1/videos/{id} | 작업을 폴링합니다. completed에서는 data[0].url, usage.completion_tokens, 실제 적용된 파라미터를 받고, failed에서는 공급자의 코드와 메시지가 담긴 구조화된 오류를 받습니다. |
DELETE /v1/videos/{id} | 작업을 취소합니다. queued 상태의 작업만 취소할 수 있으며, 취소된 작업은 과금되지 않습니다. |
GET /v1/videos/models | 키로 사용할 수 있는 동영상 모델을 모델별 해상도/길이 제약과 가격과 함께 나열합니다. |
동기 슈거 — Prefer: wait
생성 호출에 Prefer: wait 또는 Prefer: wait=N 헤더(N은 1..60초로 제한)를 추가하면 게이트웨이가 요청을 열어 둡니다. 작업이 창 안에 끝나면 동영상 URL과 usage가 포함된 최종 객체가 바로 반환되어 폴링이 필요 없습니다. 제때 끝나지 않으면 호출은 우아하게 강등됩니다: 현재 상태 객체를 받고(오류 없음, 작업은 계속 실행) 평소처럼 폴링을 이어가면 됩니다.
요청 본문
| 매개변수 | 유형 | 설명 |
|---|---|---|
model* | string | 사용할 동영상 모델(예: seedance-1-5-pro-251215). GET /v1/videos/models로 사용 가능한 모델을 모두 나열하세요. |
prompt* | string | 원하는 동영상의 텍스트 설명. |
image | string | string[] | image-to-video 입력: 이미지 1장 = 첫 프레임, 2장 = 첫 + 마지막 프레임. 각 항목은 data URI 또는 https URL입니다. |
resolution | string | 출력 해상도: 480p, 720p, 1080p 또는 4k. 지원 범위는 모델마다 다릅니다 — 모델 표 참고. |
ratio | string | 화면 비율: 16:9, 4:3, 1:1, 3:4, 9:16, 21:9 또는 adaptive. |
duration | integer | 클립 길이(초, 모델별 범위는 2..15 이내). 일부 모델은 -1도 허용하며 이 경우 모델이 길이를 선택합니다. |
seed | integer | 재현 가능한 출력을 위한 선택적 시드(지원 모델에 한함). |
watermark | boolean | 공급자 워터마크를 렌더링할지 여부. |
generate_audio | boolean | 오디오 트랙 생성 여부(기본 true). 이중 요율 모델에서는 가격이 달라집니다 — 모델 표 참고. |
사용 가능한 모델
모델 사용 가능 여부는 배포 환경에 따라 다릅니다. 모델별 해상도/길이 제약과 가격을 포함한 실시간, 규정 인식 목록은 GET /v1/videos/models에서 가져오세요. 현재 라인업:
| 모델 | 해상도 | 길이 | 가격 | 참고 |
|---|---|---|---|---|
dreamina-seedance-2-0-260128 | 480p · 720p · 1080p · 4k | 4–15 s | 480p/720p $7.0 · 1080p $7.7 · 4k $4.0 | 2.0 플래그십; 최대 4K |
dreamina-seedance-2-0-fast-260128 | 480p · 720p | 4–15 s | $5.6 | 더 빠른 2.0 변형 |
dreamina-seedance-2-0-mini-260615 | 480p · 720p | 4–15 s | $3.5 | 가장 작은 2.0 변형 |
seedance-1-5-pro-251215 | 480p · 720p · 1080p | 4–12 s | $2.4 audio · $1.2 muted | generate_audio에 따라 요율 변동 |
seedance-1-0-pro-fast-251015 | 480p · 720p · 1080p | 2–12 s | $1.0 | 최저가 |
가격: 1M video tokens당 USD. seedance-1-5-pro-251215는 오디오 트랙을 켜면(generate_audio: true, 기본값) $2.4, 끄면 $1.2로 과금됩니다. 나머지 모델은 해상도 구간별 단일 요율입니다.
video token과 가격
동영상은 실제 출력에서 도출되는 video token으로 과금됩니다: tokens ≈ 너비 × 높이 × 24 fps × 초 / 1024. 요율은 1M video tokens 기준이며 실제 적용된 파라미터(completed 작업에 회신됨)를 따릅니다 — 따라서 ratio: "adaptive"와 duration: -1도 모델이 실제로 만든 결과대로 과금됩니다.
seedance-1-5-pro-251215(오디오 포함) 기준 감 잡기: 480p / 16:9 / 4초 클립 ≈ 40.6K video tokens ≈ $0.10, 720p / 5초 ≈ 108.9K tokens ≈ $0.26.
과금
성공 시에만 과금됩니다: 작업이 처음 completed에 도달할 때 반환된 video token 사용량 기준으로 정확히 한 번 청구됩니다. 실패한 작업(콘텐츠 검열 거부 포함)과 취소된 작업은 과금되지 않으며, 공급자의 오류는 원인 파악이 가능하도록 그대로 전달됩니다.
반환되는 data[0].url은 사전 서명된 공급자 URL로 약 24시간 후 만료됩니다 — 즉시 다운로드하고, 장기 보관이 필요하면 자체 스토리지에 다시 호스팅하세요.
예제 — curl 한 번에 (Prefer: wait)
curl https://synthorai.io/v1/videos \
-H "Authorization: Bearer $SYNTHORAI_API_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: wait=60" \
-d '{
"model": "seedance-1-0-pro-fast-251015",
"prompt": "A corgi puppy chasing a butterfly across a meadow, cinematic",
"resolution": "480p",
"ratio": "16:9",
"duration": 4
}'
# Finished inside the wait window → the terminal object comes straight back:
{
"id": "vid_6091d8d1af805818b1470488",
"object": "video",
"model": "seedance-1-0-pro-fast-251015",
"status": "completed",
"data": [{ "url": "https://…tos….mp4?…" }],
"usage": { "completion_tokens": 40594, "total_tokens": 40594 },
"resolution": "480p", "ratio": "16:9", "duration": 4, "fps": 24,
"seed": 34142
}
# Not done in time → the current status object is returned instead (no error,
# the task keeps running) — continue polling status_url as usual. 예제 — curl 생성 + 폴링
# 1) Create — returns in ~2 s with a queued task object
curl https://synthorai.io/v1/videos \
-H "Authorization: Bearer $SYNTHORAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-1-5-pro-251215",
"prompt": "A corgi puppy chasing a butterfly across a meadow, cinematic",
"resolution": "720p",
"duration": 5,
"generate_audio": true
}'
{
"id": "vid_6091d8d1af805818b1470488",
"object": "video",
"model": "seedance-1-5-pro-251215",
"status": "queued",
"created_at": 1784619862,
"status_url": "https://synthorai.io/v1/videos/vid_6091d8d1af805818b1470488",
"cancel_url": "https://synthorai.io/v1/videos/vid_6091d8d1af805818b1470488"
}
# 2) Poll until status is terminal (completed | failed | cancelled)
curl https://synthorai.io/v1/videos/vid_6091d8d1af805818b1470488 \
-H "Authorization: Bearer $SYNTHORAI_API_KEY"
{
"id": "vid_6091d8d1af805818b1470488",
"object": "video",
"model": "seedance-1-5-pro-251215",
"status": "completed",
"data": [{ "url": "https://…tos….mp4?…" }],
"usage": { "completion_tokens": 108900, "total_tokens": 108900 },
"resolution": "720p", "ratio": "16:9", "duration": 5, "fps": 24,
"seed": 34142, "generate_audio": true
}
# 3) Download the video — the URL is pre-signed (no auth header) and expires
# in ~24 h: fetch promptly and re-host if you need it long-term.
curl -o out.mp4 "https://…tos….mp4?…" 예제 — Python (requests)
import time
import requests
BASE = "https://synthorai.io/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
task = requests.post(f"{BASE}/videos", headers=HEADERS, json={
"model": "seedance-1-5-pro-251215",
"prompt": "A corgi puppy chasing a butterfly across a meadow, cinematic",
"resolution": "720p",
"duration": 5,
}).json()
while task["status"] not in ("completed", "failed", "cancelled"):
time.sleep(5)
task = requests.get(task["status_url"], headers=HEADERS).json()
if task["status"] == "completed":
url = task["data"][0]["url"] # pre-signed, valid ~24 h — re-host promptly
with open("out.mp4", "wb") as f:
f.write(requests.get(url).content)
else:
print(task["error"]) # provider code + message, passed through verbatim 예제 — Node (fetch)
import fs from "node:fs";
const BASE = "https://synthorai.io/v1";
const HEADERS = { Authorization: `Bearer ${process.env.SYNTHORAI_API_KEY}` };
let task = await (await fetch(`${BASE}/videos`, {
method: "POST",
headers: { ...HEADERS, "Content-Type": "application/json" },
body: JSON.stringify({
model: "seedance-1-5-pro-251215",
prompt: "A corgi puppy chasing a butterfly across a meadow, cinematic",
resolution: "720p",
duration: 5,
}),
})).json();
while (!["completed", "failed", "cancelled"].includes(task.status)) {
await new Promise((r) => setTimeout(r, 5000));
task = await (await fetch(task.status_url, { headers: HEADERS })).json();
}
if (task.status === "completed") {
const url = task.data[0].url; // pre-signed, valid ~24 h — re-host promptly
fs.writeFileSync("out.mp4", Buffer.from(await (await fetch(url)).arrayBuffer()));
} else {
console.error(task.error); // provider code + message, passed through verbatim
} 멱등성
생성 호출에 다음을 전달하세요: X-Idempotency-Key 헤더로 재시도를 안전하게 만듭니다: 같은 키로 반복된 요청은 두 번째 작업을 생성(및 과금)하는 대신 409를 반환합니다. 동영상 생성은 느리고 재시도가 잦으므로 이중 과금을 방지합니다.